1
0
Fork 0
mirror of https://github.com/Yetangitu/ampache synced 2025-10-05 19:41:55 +02:00

New Import

This commit is contained in:
Karl 'vollmerk' Vollmer 2005-06-09 16:34:40 +00:00
commit bcad40a05a
326 changed files with 86336 additions and 0 deletions

85
admin/access.php Normal file
View file

@ -0,0 +1,85 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
require('../modules/init.php');
/* Scrub in the Needed vars */
$action = scrub_in($_REQUEST['action']);
$access_id = scrub_in($_REQUEST['access_id']);
$access = new Access($access_id);
if (!$user->has_access(100)) {
header("Location: http://" . conf('web_path') . "/index.php?access=denied");
exit();
}
show_template('header');
show_menu_items('Admin');
show_admin_menu('Access Lists');
show_clear();
if ( $action == 'show_confirm_delete' ) {
show_confirm_action(_("Do you really want to delete this Access Record?"), "admin/access.php", "access_id=" . $_REQUEST['access_id'] . "&action=delete_host");
}
/*!
@action delete_host
@discussion deletes an access list entry
*/
elseif ( $action == 'delete_host' ) {
$access->delete($_REQUEST['access_id']);
show_confirmation(_("Entry Deleted"),_("Your Access List Entry has been removed"),"admin/access.php");
} // delete_host
/*!
@action add_host
@discussion add a new access list entry
*/
elseif ($action == 'add_host') {
$access->create($_REQUEST['name'], $_REQUEST['start'],$_REQUEST['end'],$_REQUEST['level']);
show_confirmation(_("Entry Added"),_("Your new Access List Entry has been created"),"admin/access.php");
} // add_host
/*!
@action show_add_host
@discussion show the add host box
*/
elseif ( $action == 'show_add_host' ) {
include(conf('prefix') . "/templates/show_add_access.inc");
}
else {
$list = array();
$list = $access->get_access_list();
include(conf('prefix') ."/templates/show_access_list.inc");
}
echo "<br /><br />";
show_admin_menu('Access Lists');
show_menu_items('Admin');
?>
</body>
</html>

114
admin/album.php Normal file
View file

@ -0,0 +1,114 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Admin Album Mojo
Update the album information for the site.
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
header("Location:" . conf('web_path') . "/index.php?access=denied");
exit();
}
if ( $action == 'Change Name' ) {
update_album_name($album, $new_name);
if ( $update_tag ) {
// get songs associated with this
$songs = get_songs_from_album($album);
// run update_local_mp3
$total_updated = update_local_mp3($new_name, 'album', $songs);
$update_text = "Updated the database and $total_updated local files.";
}
// set the action to view so everybody can see the changes
$action = 'View';
}
show_template('header');
show_menu_items('Admin');
show_admin_menu('Catalog');
?>
<p>Use this form to change the name(s) of albums in the database. In order to update your
local MP3's your Apache user must have write-permission to your MP3's.</p>
<form name="album" method="post" action="album.php">
<table>
<tr>
<td>Select Album:</td>
<td> <?php show_album_pulldown($album) ?> </td>
<td> <input type=submit name=action value=View> </td>
</tr>
</table>
</form>
<hr>
<?php
// if album exists then show some info
if ( $album and $action == 'View' ) {
$album_name = get_album_name($album);
?>
<p style="color: red;"><?= $update_text ?></p>
<form name="album_change" method=post action="album.php">
<table>
<tr>
<td>Album Name:</td>
<td><input type=text name="new_name" value="<?= $album_name ?>" size="50"></td>
<td> &nbsp; </td>
<td><input type=submit name=action value="Change Name"></td>
<tr>
<td> &nbsp; </td> <td><input type="checkbox" name="update_tag">
Update MP3 tag <b>Note: this will only modify your local MP3's</b>
</td>
</tr>
</table>
<input type=hidden name=album value="<?= $album ?>">
</form>
<?php
$song_ids = get_song_ids_from_album($album);
show_songs($song_ids, 0);
}
show_footer();
?>
</body>
</html>

121
admin/artist.php Normal file
View file

@ -0,0 +1,121 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Admin Artist page
Update the artist information for the site.
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
header("Location:". conf('web_path') . "/index.php?access=denied");
exit();
}
$dbh = dbh();
if ( $action == 'Change Name' ) {
if ( $settings[demo_mode] == 'false' && $username != $settings[demo_user] ) {
$old_artist_name = get_artist_name($artist);
update_artist_name($artist, $new_name);
if ( $update_tag ) {
// get songs associated with this
$song_ids = get_song_ids_from_artist($artist);
// run update_local_mp3
$total_updated = update_local_mp3($new_name, 'artist', $song_ids);
$update_text = "Updated $old_artist_name to $new_name and $total_updated local files.";
}
else {
$update_text = "Updated $old_artist_name to $new_name.";
}
// set the action to view so everybody can see the changes
$action = 'View';
}
}
show_template('header');
show_menu_items("..");
show_admin_menu('Catalog');
?>
<p>Use this form to change the name(s) of artists in the database. In order to update your
local MP3's your Apache user must have write-permission to your MP3's.</p>
<form name="artist" method="post" action="artist.php">
<table>
<tr>
<td>Select Artist:</td>
<td> <?php show_artist_pulldown($artist) ?> </td>
<td> <input type=submit name=action value=View> </td>
</tr>
</table>
</form>
<hr>
<?php
// if artist exists then show some info
if ( $artist and $action == 'View' ) {
$sql = "SELECT name FROM artist WHERE id='$artist'";
$db_result = mysql_query($sql, $dbh);
$r = mysql_fetch_row($db_result);
$artist_name = $r[0];
?>
<p style="color: red;"><?= $update_text ?></p>
<form name="artist_change" method=post action="artist.php">
<table>
<tr>
<td>Artist Name:</td> <td><input type=text name="new_name" value="<?= $artist_name ?>" size="50"></td>
<td> &nbsp; </td> <td><input type=submit name=action value="Change Name"></td>
</tr>
<tr>
<td> &nbsp; </td> <td><input type="checkbox" name="update_tag">
Update MP3 tag <b>Note: this will only modify your local MP3's</b>
</td>
</tr>
</table>
<input type="hidden" name="artist" value="<?= $artist ?>">
</form>
<?php
show_albums_for_artist($artist);
}
?>
</body>
</html>

282
admin/catalog.php Normal file
View file

@ -0,0 +1,282 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Admin Catalog
This document handles actions for catalog creation and passes them off to the catalog class
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
access_denied();
}
/* Set any vars we are going to need */
$catalog = new Catalog($_REQUEST['catalog_id']);
show_template('header');
/* Generate the menus */
show_menu_items('Admin');
show_admin_menu('Catalog');
show_clear();
/* Big switch statement to handle various actions */
switch ($_REQUEST['action']) {
case 'fixed':
delete_flagged($flag);
$type = 'show_flagged_songs';
include(conf('prefix') . '/templates/flag.inc');
break;
case _("Add to Catalog(s)"):
if (conf('demo_mode')) { break; }
if ($_REQUEST['catalogs'] ) {
foreach ($_REQUEST['catalogs'] as $catalog_id) {
$catalog = new Catalog($catalog_id);
$catalog->add_to_catalog($_REQUEST['update_type']);
}
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case _("Add to all Catalogs"):
if (conf('demo_mode')) { break; }
$catalogs = $catalog->get_catalogs();
foreach ($catalogs as $data) {
$data->add_to_catalog($_REQUEST['update_type']);
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case _("Update Catalog(s)"):
if (conf('demo_mode')) { break; }
if (isset($_REQUEST['catalogs'])) {
foreach ($_REQUEST['catalogs'] as $catalog_id) {
$catalog = new Catalog($catalog_id);
$catalog->verify_catalog($catalog_id->id,$_REQUEST['update_type']);
}
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case _("Update All Catalogs"):
if (conf('demo_mode')) { break; }
$catalogs = $catalog->get_catalogs();
foreach ($catalogs as $data) {
$data->verify_catalog($data->id,$_REQUEST['update_type']);
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case 'delete_catalog':
if (conf('demo_mode')) { break; }
if ($_REQUEST['confirm'] === 'Yes') {
$catalog = new Catalog($_REQUEST['catalog_id']);
$catalog->delete_catalog();
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case 'remove_disabled':
if (conf('demo_mode')) { break; }
$song = $_REQUEST['song'];
if (count($song)) {
$catalog->remove_songs($song);
echo "<p align=\"center\">Songs Removed... </p>";
}
else {
echo "<p align=\"center\">No Songs Removed... </p>";
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case _("Clean Catalog(s)"):
if (conf('demo_mode')) { break; }
// Make sure they checked something
if (isset($_REQUEST['catalogs'])) {
foreach($_REQUEST['catalogs'] as $catalog_id) {
$catalog = new Catalog($catalog_id);
$catalog->clean_catalog(0,$_REQUEST['update_type']);
} // end foreach catalogs
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case 'update_catalog_settings':
if (conf('demo_mode')) { break; }
$id = strip_tags($_REQUEST['catalog_id']);
$name = strip_tags($_REQUEST['name']);
$id3cmd = strip_tags($_REQUEST['id3_set_command']);
$rename = strip_tags($_REQUEST['rename_pattern']);
$sort = strip_tags($_REQUEST['sort_pattern']);
/* Setup SQL */
$sql = "UPDATE catalog SET " .
" name = '$name'," .
" id3_set_command = '$id3cmd'," .
" rename_pattern = '$rename'," .
" sort_pattern = '$sort'" .
" WHERE id = '$id'";
$result = mysql_query($sql, dbh());
include(conf('prefix') . '/templates/catalog.inc');
break;
case _("Clean All Catalogs"):
if (conf('demo_mode')) { break; }
$catalogs = $catalog->get_catalogs();
$dead_files = array();
foreach ($catalogs as $catalog) {
$catalog->clean_catalog(0,$_REQUEST['update_type']);
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case 'add_catalog':
if (conf('demo_mode')) { break; }
if ($_REQUEST['path'] AND $_REQUEST['name']) {
/* Throw all of the album art types into an array */
$art = array('id3'=>$_REQUEST['art_id3v2'],'amazon'=>$_REQUEST['art_amazon'],'folder'=>$_REQUEST['art_folder']);
/* Create the Catalog */
$catalog->new_catalog($_REQUEST['path'],
$_REQUEST['name'],
$_REQUEST['id3set_command'],
$_REQUEST['rename_pattern'],
$_REQUEST['sort_pattern'],
$_REQUEST['type'],
$_REQUEST['gather_art'],
$_REQUEST['parse_m3u'],
$art);
include(conf('prefix') . '/templates/catalog.inc');
}
else {
$error = "Please complete the form.";
include(conf('prefix') . '/templates/add_catalog.inc');
}
break;
case 'really_clear_stats':
if (conf('demo_mode')) { break; }
if ($_REQUEST['confrim'] == 'Yes') {
clear_catalog_stats();
}
include(conf('prefix') . '/templates/catalog.inc');
break;
case 'show_add_catalog':
include(conf('prefix') . '/templates/add_catalog.inc');
break;
case 'clear_now_playing':
if (conf('demo_mode')) { break; }
clear_now_playing();
show_confirmation(_("Now Playing Cleared"),_("All now playing data has been cleared"),"/admin/catalog.php");
break;
case 'Clear Catalog':
if (conf('demo_mode')) { break; }
show_confirm_action(_("Do you really want to clear your catalog?"),
"/admin/catalog.php", "action=really_clear_catalog");
print("<hr>\n");
break;
case 'clear_stats':
if (conf('demo_mode')) { break; }
show_confirm_action(_("Do you really want to clear the statistics for this catalog?"),
"/admin/catalog.php", "action=really_clear_stats");
print("<hr>\n");
break;
case 'show_disabled':
if (conf('demo_mode')) { break; }
$songs = $catalog->get_disabled();
if (count($songs)) {
require (conf('prefix') . '/templates/show_disabled_songs.inc');
}
else {
echo "<p class=\"error\" align=\"center\">No Disabled songs found</p>";
}
break;
case 'show_delete_catalog':
if (conf('demo_mode')) { break; }
show_confirm_action(_("Do you really want to delete this catalog?"),
"admin/catalog.php",
"catalog_id=" . $_REQUEST['catalog_id'] . "&action=delete_catalog");
break;
case 'show_flagged_songs':
if (conf('demo_mode')) { break; }
$type = $_REQUEST['action'];
include (conf('prefix') . '/templates/flag.inc');
break;
case 'Update Flags':
if (conf('demo_mode')) { break; }
echo "<pre>";
print_r($_REQUEST);
echo "</pre>";
break;
case 'show_customize_catalog':
include(conf('prefix') . '/templates/customize_catalog.inc');
break;
case 'gather_album_art':
echo "<b>" . _("Starting Album Art Search") . ". . .</b><br /><br />\n";
flush();
$catalogs = $catalog->get_catalogs();
foreach ($catalogs as $data) {
$data->get_album_art();
}
echo "<b>" . _("Album Art Search Finished") . ". . .</b><br />\n";
break;
// (Added by Cucumber 20050216)
case 'dump_album_art':
$catalogs = $catalog->get_catalogs();
foreach ($catalogs as $data) {
$data->dump_album_art();
}
break;
default:
include(conf('prefix') . '/templates/catalog.inc');
} // end switch
echo "<br /><br />";
show_admin_menu('Catalog');
show_menu_items('Admin');
?>
</body>
</html>

59
admin/duplicates.php Normal file
View file

@ -0,0 +1,59 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Allows users to search for duplicate songs in their catalogs
require_once ("../modules/init.php");
require_once( conf('prefix').'/lib/duplicates.php');
if (!$user->has_access(100)) {
header ("Location: " . conf('web_path') . "/index.php?access=denied");
exit();
}
$action = scrub_in($_REQUEST['action']);
$search_type = scrub_in($_REQUEST['search_type']);
show_template('header');
show_menu_items('Admin');
show_admin_menu('Users');
switch ($action)
{
case 'search':
$flags = get_duplicate_songs($search_type);
show_duplicate_songs($flags,$search_type);
break;
default:
show_duplicate_searchbox($search_type);
}
show_footer();
?>
</body>
</html>

91
admin/flags.php Normal file
View file

@ -0,0 +1,91 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Flags Mojo
*/
require_once ("../modules/init.php");
require_once( conf('prefix').'/lib/flag.php');
if (!$user->has_access(100)) {
header ("Location: " . conf('web_path') . "/index.php?access=denied");
exit();
}
$action = scrub_in($_REQUEST['action']);
show_template('header');
show_menu_items('Admin');
show_admin_menu('Users');
switch ($action)
{
case 'show':
$flags = get_flagged_songs();
show_flagged_songs($flags);
break;
case 'Set Flags':
case 'Update Flags':
$flags = scrub_in($_REQUEST['song']);
update_flags($flags);
$newflags = get_flagged_songs();
show_flagged_songs($newflags);
break;
case 'Edit Selected':
$flags = scrub_in($_REQUEST['song']);
$count = add_to_edit_queue($flags);
if($count) show_edit_flagged();
break;
case 'Next':
$song = scrub_in($_REQUEST['song']);
update_song_info($song);
show_edit_flagged();
// Pull song ids from an edit queue in $_SESSION,
// And edit them one at a time
break;
case 'Skip':
$count = add_to_edit_queue(scrub_in($_REQUEST['song']));
if($count) show_edit_flagged();
case 'Flag Songs':
break;
case 'Remove Flags':
break;
case 'Clear Edit List':
unset($_SESSION['edit_queue']);
case 'Done':
$song = scrub_in($_REQUEST['song']);
update_song_info($song);
default:
$flags = get_flagged_songs();
show_flagged_songs($flags);
}
show_footer();
?>
</body>
</html>

96
admin/index.php Normal file
View file

@ -0,0 +1,96 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Admin Index
Do most of the dirty work of displaying the mp3 catalog
*/
require ("../modules/init.php");
$action = scrub_in($_REQUEST['action']);
if (!$user->has_access(100)) {
header ("Location: " . conf('web_path') . "/index.php?access=denied");
exit();
}
// let's set the preferences here so that they take affect on the fly
if ( $action == 'Update Preferences' ) {
update_site_preferences($preferences_id, 'true', $new_m_host, $new_w_host,
$new_site_title, $new_login_message, $new_session_lifetime, $new_font,
$new_background_color, $new_primary_color, $new_secondary_color,
$new_primary_font_color, $new_secondary_font_color,
$new_error_color, $new_popular_threshold);
// reload the preferences now
set_preferences();
}
show_template('header');
show_menu_items('Admin');
if ( $action == 'show_site_preferences' ) {
show_admin_menu('Site Preferences');
}
elseif ( ($action == 'show_users') || ($action == 'show_new_user')) {
show_admin_menu('Users');
}
elseif ( $action == 'show_update_catalog' ) {
show_admin_menu('Catalog');
}
else {
show_admin_menu('...');
}
if ( $action == 'Update Preferences' ) {
$action = 'show_preferences';
}
elseif ( $action == 'show_update_catalog' ) {
show_update_catalog();
}
elseif ( $action == 'show_file_manager' ) {
show_file_manager();
}
elseif ( $action == 'show_site_preferences' ) {
$user = new User(0);
require (conf('prefix') . "/templates/show_preferences.inc");
}
elseif ( $action == 'show_preferences' ) {
$user = new User($_REQUEST['user_id']);
require (conf('prefix') . "/templates/show_preferences.inc");
}
elseif ( $action == 'show_orphaned_files' ) {
show_orphaned_files();
}
else {
require (conf('prefix') . "/templates/show_admin_index.inc");
} // if they didn't pick anything
echo "<br /><br />";
show_admin_menu('');
show_menu_items('Admin');
?>
</body>
</html>

139
admin/mail.php Normal file
View file

@ -0,0 +1,139 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Mail Admin Page
Means to mail your users or give updates about the server
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
access_denied();
}
$action = scrub_in($_POST['action']);
$to = scrub_in($_REQUEST['to']);
$subject = stripslashes(scrub_in($_POST['subject']));
$message = stripslashes(scrub_in($_POST['message']));
if ( $action == 'send_mail' && !conf('demo_mode')) {
$user = new User(0,$_SESSION['userdata']['id']);
// do the mail mojo here
if ( $to == 'all' ) {
$sql = "SELECT * FROM user WHERE email IS NOT NULL";
}
elseif ( $to == 'users' ) {
$sql = "SELECT * FROM user WHERE access='users' AND email IS NOT NULL";
}
elseif ( $to == 'admins' ) {
$sql = "SELECT * FROM user WHERE access='admin' AND email IS NOT NULL";
}
$db_result = mysql_query($sql, dbh());
$recipient = '';
while ( $u = mysql_fetch_object($db_result) ) {
$recipient .= "$u->fullname <$u->email>, ";
}
// Remove the last , from the recipient
$recipient = rtrim($recipient,",");
$from = $user->fullname."<".$user->email.">";
// woohoo!!
mail ($from, $subject, $message,
"From: $from\r\n".
"Bcc: $recipient\r\n");
// tell them that it was sent
$complete_text = "Your message was successfully sent.";
}
if ( empty($to) ) {
$to = 'all';
}
if ( empty($subject) ) {
$site_title = conf('site_title');
$subject = "[$site_title] ";
}
show_template('header');
show_menu_items('Admin');
show_admin_menu('Mail Users');
show_clear();
?>
<form name="mail" method="post" action="<?php echo conf('web_path'); ?>/admin/mail.php" enctype="multipart/form-data">
<p><font color="<?php echo $error_color; ?>"><?php echo $complete_text; ?></font></p>
<table>
<tr>
<td><?php echo _("Mail to"); ?>:</td>
<td>
<select name="to">
<option value="all" <?php if ($to == 'all') { echo "SELECTED"; } ?>>All</option>
<option value="users" <?php if ($to == 'user') { echo "SELECTED"; } ?>>Users</option>
<option value="admins" <?php if ($to == 'admin') { echo "SELECTED"; } ?>>Admins</option>
</select>
</td>
</tr>
<tr>
<td><?php echo _("Subject"); ?>:</td>
<td>
<input name="subject" value="<?php echo $_POST['subject']; ?>" size="50"></input>
</td>
</tr>
<tr>
<td valign="top"><?php echo _("Message"); ?>:</td>
<td>
<textarea class="input" name="message" rows="20" cols="70"><?php echo $message; ?></textarea>
</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>
<input type="hidden" name="action" value="send_mail" />
<input type="submit" value="<?php echo _("Send Mail"); ?>" />
</td>
</tr>
</table>
</form>
<br /><br />
<?php
show_admin_menu('Mail Users');
show_menu_items('Admin');
?>
</body>
</html>

71
admin/orphan.php Normal file
View file

@ -0,0 +1,71 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Orphaned Admin Page
View and edit orphan files
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
header("Location: " . conf('web_path') . "/index.php?access=denied");
exit();
}
if ( $type and $action == 'show_songs' ) {
print("<p style=\"font-size: 12px; font-weight: bold;\"> Orphaned Songs with missing $type information </p>");
$song_ids = get_orphan_songs($type);
show_songs($song_ids);
}
show_template('header');
show_menu_items('Admin');
show_admin_menu('Catalog');
if ( $action == 'show_orphan_songs' ) {
print("<p style=\"font-size: 12px; font-weight: bold;\"> Orphaned songs with no artist </p>");
$song_ids = get_orphan_songs();
show_songs($song_ids);
}
elseif ( $action == 'show_orphan_albums' ) {
print("<p style=\"font-size: 12px; font-weight: bold;\"> Orphaned albums with no name </p>");
$song_ids = get_orphan_albums();
show_songs($song_ids);
}
?>
<hr>
</body>
</html>

92
admin/preferences.php Normal file
View file

@ -0,0 +1,92 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Preferences page
Preferences page for whole site, and where
the admins do editing of other users preferences
*/
require('../modules/init.php');
if (!$user->has_access(100)) {
access_denied();
}
$user_id = intval(scrub_in($_REQUEST['user_id']));
switch(scrub_in($_REQUEST['action'])) {
case 'user':
$temp_user = new User(0,$user_id);
$user_id = $temp_user->id;
$fullname = "ADMIN - " . $temp_user->fullname;
$preferences = $temp_user->get_preferences();
break;
case 'update_preferences':
if (conf('demo_mode')) { break; }
update_preferences($user_id);
if ($user_id != '0') {
$temp_user = new User(0,$user_id);
$fullname = "ADMIN - " . $temp_user->fullname;
$preferences = $temp_user->get_preferences();
}
else {
$preferences = get_site_preferences();
}
break;
case 'fix_preferences':
$temp_user = new User(0,$user_id);
$temp_user->fix_preferences();
$preferences = $temp_user->get_preferences();
break;
default:
$user_id = 0;
$preferences = get_site_preferences();
$fullname = "Site";
break;
} // End Switch Action
// HEADER
show_template('header');
show_menu_items('Admin');
show_admin_menu('Admin Preferences');
show_clear();
// HEADER
// Set Target
$target = "/admin/preferences.php";
// Show the default preferences page
require (conf('prefix') . "/templates/show_preferences.inc");
// FOOTER
show_admin_menu('Admin Preferences');
show_menu_items('Admin');
?>

182
admin/song.php Normal file
View file

@ -0,0 +1,182 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Song Admin Files
Edit song information. Can be just DB or file based (update MP3 ID3 tags).
*/
require('../modules/init.php');
require_once(conf('prefix').'/lib/flag.php');
if (!$user->has_access('100')) {
access_denied();
}
$action = scrub_in($_REQUEST['action']);
$song = scrub_in($_REQUEST['song']);
show_template('header');
show_menu_items('Admin');
show_admin_menu('Catalog');
$song_obj = new Song($_REQUEST['song_id']);
switch($action)
{
case "Update":
case "update";
update_song_info($song);
edit_song_info($song);
break;
case "Edit":
case "edit":
edit_song_info($song);
break;
case "disable":
// If we pass just one, make it still work
if (!is_array($_REQUEST['song_ids'])) { $song_obj->update_enabled('disabled',$_REQUEST['song_ids']); }
else {
foreach ($_REQUEST['song_ids'] as $song_id) {
$song_obj->update_enabled('disabled',$song_id);
} // end foreach
} // end else
show_confirmation(_("Songs Disabled"),_("The requested song(s) have been disabled"),return_referer());
break;
case "enabled":
// If we pass just one, make it still work
if (!is_array($_REQUEST['song_ids'])) { $song_obj->update_enabled('enabled',$_REQUEST['song_ids']); }
else {
foreach ($_REQUEST['song_ids'] as $song_id) {
$song_obj->update_enabled('enabled',$song_id);
} // end foreach
} // end else
show_confirmation(_("Songs Enabled"),_("The requested song(s) have been enabled"),return_referer());
break;
default:
echo "Don't know what to do yet.";
}
/*
@function edit_song_info
@discussion yea this is just wrong
*/
function edit_song_info($song) {
$info = new Song($song);
preg_match("/^.*\/(.*?)$/",$info->file, $short);
$filename = htmlspecialchars($short[1]);
if(preg_match('/\.ogg$/',$short[1]))
{
$ogg = TRUE;
$oggwarn = "<br/><br><em>This file is an OGG file, which Ampache only has limited support for.<br/>";
$oggwarn .= "You can make changes to the database here, but Ampache will not change the actual file's information.</em><br/><br/>";
}
echo <<<EDIT_SONG_1
<p><b>Editing $info->title</b></p>
<form name="update_song" method="post" action="song.php">
<table class="border" cellspacing="0">
<tr class="table-header">
<td colspan="3"><b>Editing $info->title</b></td>
</tr>
<tr class="odd">
<td>File:</td>
<td colspan="2">$filename $oggwarn</td>
</tr>
<tr class="odd">
<td>Title:</td>
<td colspan="2"><input type="text" name="title" size="60" value="$info->title"></td>
</tr>
<tr class="even">
<td>Artist:</td>
<td>
EDIT_SONG_1;
show_artist_pulldown($info->artist);
echo <<<EDIT_SONG_2
</td>
<td>or <input type="text" name="new_artist" size="30" value=""></td>
</tr>
<tr class="odd">
<td>Album:</td>
<td>
EDIT_SONG_2;
show_album_pulldown($info->album);
echo <<<EDIT_SONG_3
</td>
<td>or <input type="text" name="new_album" size="30" value=""></td>
</tr>
<tr class="even">
<td>Track:</td>
<td colspan="2"><input type="text" size="4" maxlength="4" name="track" value="$info->track"></input></td>
</tr>
<tr class="odd">
<td>Genre:</td>
<td colspan="2">
EDIT_SONG_3;
show_genre_pulldown($info->genre, 1);
echo <<<EDIT_SONG_4
<tr class="even">
<td>Year</td>
<td colspan="2"><input type="text" size="4" maxlength="4" name="year" value="$info->year"></input></td>
</tr>
EDIT_SONG_4;
if(!$ogg)
{
echo <<<EDIT_SONG_5
<tr class="even">
<td>&nbsp;</td>
<td><input type="checkbox" name="update_id3" value="yes">&nbsp;Update id3 tags</input></td>
<td>&nbsp;</td>
</tr>
EDIT_SONG_5;
}
echo <<<EDIT_SONG_6
<tr class="odd">
<td> &nbsp; </td>
<td colspan="2">
<input type="hidden" name="song" value="$song" />
<input type="hidden" name="current_artist_id" value="$info->artist" />
<input type="submit" name="action" value="Update" />
</td>
</tr>
</table>
</form>
EDIT_SONG_6;
}
?>
<hr>
</body>
</html>

181
admin/users.php Normal file
View file

@ -0,0 +1,181 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Users Admin Page
Handles User management functions
*/
require_once ("../modules/init.php");
if (!$user->has_access(100)) {
access_denied();
}
$action = scrub_in($_REQUEST['action']);
show_template('header');
show_menu_items('Admin');
show_admin_menu('Users');
show_clear();
$user_id = scrub_in($_REQUEST['user']);
$temp_user = new User($user_id);
switch ($action) {
case 'edit':
if (conf('demo_mode')) { break; }
show_user_form($temp_user->id,
$temp_user->username,
$temp_user->fullname,
$temp_user->email,
$temp_user->access,
'edit_user',
'');
break;
case 'update_user':
if (conf('demo_mode')) { break; }
/* Clean up the variables */
$username = scrub_in($_REQUEST['new_username']);
$fullname = scrub_in($_REQUEST['new_fullname']);
$email = scrub_in($_REQUEST['new_email']);
$access = scrub_in($_REQUEST['user_access']);
$pass1 = scrub_in($_REQUEST['new_password_1']);
$pass2 = scrub_in($_REQUEST['new_password_2']);
/* Setup the temp user */
$thisuser = new User($username);
/* Verify Input */
if (empty($username)) {
$GLOBALS['error']->add_error('username',_("Error Username Required"));
}
if ($pass1 !== $pass2 AND !empty($pass1)) {
$GLOBALS['error']->add_error('password',_("Error Passwords don't match"));
}
/* If we've got an error then break! */
if ($GLOBALS['error']->error_state) {
show_user_form($temp_user->id,
$thisuser->username,
$thisuser->fullname,
$thisuser->email,
$thisuser->access,
'edit_user',
'');
break;
} // if we've had an oops!
if ($access != $thisuser->access) {
$thisuser->update_access($access);
}
if ($email != $thisuser->email) {
$thisuser->update_email($email);
}
if ($username != $thisuser->username) {
$thisuser->update_username($username);
}
if ($fullname != $user->fullname) {
$thisuser->update_fullname($fullname);
}
if ($pass1 == $pass2 && strlen($pass1)) {
$thisuser->update_password($pass1);
}
show_confirmation("User Updated", $thisuser->username . "'s information has been updated","admin/users.php");
break;
case 'add_user':
if (conf('demo_mode')) { break; }
$username = scrub_in($_REQUEST['new_username']);
$fullname = scrub_in($_REQUEST['new_fullname']);
$email = scrub_in($_REQUEST['new_email']);
$access = scrub_in($_REQUEST['user_access']);
$pass1 = scrub_in($_REQUEST['new_password_1']);
$pass2 = scrub_in($_REQUEST['new_password_2']);
if (($pass1 !== $pass2)) {
$GLOBALS['error']->add_error('password',_("Error Passwords don't match"));
}
if (empty($username)) {
$GLOBALS['error']->add_error('username',_("Error Username Required"));
}
if (!$user->create($username, $fullname, $email, $pass1, $access)) {
$GLOBALS['error']->add_error('general',"Error: Insert Failed");
}
/* If we end up with an error */
if ($GLOBALS['error']->error_state) {
show_user_form('','$username','$fullname','$email','$access','new_user','');
break;
}
show_confirmation("New User Added",$username . " has been created with an access level of " . $access,"admin/users.php");
break;
case 'delete':
if (conf('demo_mode')) { break; }
show_confirm_action(_("Are you sure you want to permanently delete") . " $temp_user->fullname ($temp_user->username) ?",
"admin/users.php",
"action=confirm_delete&user=$temp_user->username");
break;
case 'confirm_delete':
if (conf('demo_mode')) { break; }
if ($_REQUEST['confirm'] == _("No")) { show_manage_users(); break; }
if ($temp_user->delete()) {
show_confirmation(_("User Deleted"), "$temp_user->username has been Deleted","admin/users.php");
}
else {
show_confirmation(_("Delete Error"), _("Unable to delete last Admin User"),"admin/users.php");
}
break;
case 'show_add_user':
if (conf('demo_mode')) { break; }
show_user_form('','','','','','new_user','');
break;
case 'update':
case 'disabled':
if (conf('demo_mode')) { break; }
$level = scrub_in($_REQUEST['level']);
$thisuser = new User($_REQUEST['user']);
if ($_SESSION['userdata']['access'] == 'admin') {
$thisuser->update_access($level);
}
show_manage_users();
break;
default:
show_manage_users();
}
echo "<br /><br />";
show_admin_menu('Users');
show_menu_items('Admin');
?>
</body>
</html>

59
albumart.php Normal file
View file

@ -0,0 +1,59 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
@header Album Art
This pulls album art out of the file using the getid3 library
and dumps it to the browser as an image mime type.
*/
require('modules/init.php');
$album = new Album($_REQUEST['id']);
// Check db first
$r = $album->get_art($_REQUEST['fast']);
if (isset($r->art)) {
$art = $r->art;
$mime = $r->art_mime;
$found = 1;
}
if (!$found) {
// Print a transparent gif instead
// header('Content-type: image/jpg');
// readfile(conf('prefix') . "/docs/images/blankalbum.jpg");
header('Content-type: image/gif');
readfile(conf('prefix') . conf('theme_path') . "/images/blankalbum.gif");
}
else {
// Print the album art
$extension = substr($mime,strlen($mime)-3,3);
header("Content-type: $mime");
header("Content-Disposition: filename=" . $album->name . "." . $extension);
echo $art;
}
?>

181
albums.php Normal file
View file

@ -0,0 +1,181 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
Do most of the dirty work of displaying the mp3 catalog
*/
require_once("modules/init.php");
// We'll set any input parameters here
if(!isset($_REQUEST['match'])) { $_REQUEST['match'] = "Browse"; }
if(isset($_REQUEST['match'])) $match = scrub_in($_REQUEST['match']);
if(isset($_REQUEST['album'])) $album = scrub_in($_REQUEST['album']);
if(isset($_REQUEST['artist'])) $artist = scrub_in($_REQUEST['artist']);
$_REQUEST['artist_id'] = scrub_in($_REQUEST['artist_id']);
show_template('header');
show_menu_items('Albums');
show_clear();
if ($_REQUEST['action'] === 'clear_art') {
if (!$user->has_access('25')) { access_denied(); }
$album = new Album($_REQUEST['album_id']);
$album->clear_art();
show_confirmation(_("Album Art Cleared"),_("Album Art information has been removed form the database"),"/albums.php?action=show&album=" . $album->id);
} // clear_art
// if we have album
elseif (isset($album)) {
$album = new Album($album);
$album->format_album();
require (conf('prefix') . "/templates/show_album.inc");
if (isset($artist) && $artist != 0) {
$song_ids = get_song_ids_from_artist_and_album($artist, $album->id);
}
else {
$song_ids = get_song_ids_from_album($album->id);
}
show_songs($song_ids,0,$album);
} // isset(album)
// Finds the Album art from amazon
elseif ($_REQUEST['action'] === 'find_art') {
if (!$user->has_access('25')) { access_denied(); }
/* Echo notice if no amazon token is found, but it's enabled */
if (in_array('amazon',conf('album_art_order')) AND !conf('amazon_developer_key')) {
echo "<br /><div class=\"fatalerror\">Error: No Amazon Developer Key set, amazon album art searching will not work</div>";
}
$album = new Album($_REQUEST['album_id']);
$result = $album->find_art($_REQUEST['cover']);
if ($result) {
show_confirmation(_("Album Art Located"),_("Album Art information has been located in Amazon. If incorrect, click \"Reset Album Art\" below to remove the artwork."),"/albums.php?action=show&album=" . $album->id);
echo "&nbsp;[ <a href=\"" . conf('web_path') . "/albums.php?action=clear_art&album_id=" . $album->id . "\">Reset Album Art</a> ]";
echo "<p align=left><img src=\"" . conf('web_path') . "/albumart.php?id=" . $album->id . "\"></p>";
echo "<p><form name=\"cover\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">";
echo "Enter URL to album art ";
echo "<input type=\"text\" size=\"40\" id=\"cover\" name=\"cover\" value=\"\" />\n";
echo "<input type=\"hidden\" name=\"action\" value=\"find_art\" />\n";
echo "<input type=\"hidden\" name=\"album_id\" value=\"$album->id\" />\n";
echo "<input type=\"submit\" value=\"" . _("Get Art") . "\" />\n";
echo "</form>";
}
else {
show_confirmation(_("Album Art Not Located"),_("Album Art could not be located at this time. This may be due to Amazon being busy, or the album not being present in their collection."),"/albums.php?action=show&album=" . $album->id);
echo "<p><form name=\"cover\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">";
echo "Enter URL to album art ";
echo "<input type=\"text\" size=\"40\" id=\"cover\" name=\"cover\" value=\"\" />";
echo "<input type=\"hidden\" name=\"action\" value=\"find_art\" />";
echo "<input type=\"hidden\" name=\"album_id\" value=\"$album->id\" />&nbsp;&nbsp;&nbsp;";
echo "<input type=\"submit\" value=\"" . _("Get Art") . "\" />\n";
echo "</form>";
}
} // find_art
// Updates Album from tags
elseif ($_REQUEST['action'] === 'update_from_tags') {
$album = new Album($_REQUEST['album_id']);
echo "<br /><b>" . _("Starting Update from Tags") . ". . .</b><br />\n";
$catalog = new Catalog();
$catalog->update_single_item('album',$_REQUEST['album_id']);
echo "<br /><b>" . _("Update From Tags Complete") . "</b> &nbsp;&nbsp;";
echo "<a href=\"" . conf('web_path') . "/albums.php?action=show&album=" . $_REQUEST['album_id'] . "\">[" . _("Return") . "]</a>";
} // update_from_tags
else {
if (strlen($_REQUEST['match']) < '1') { $match = 'none'; }
// Setup the View Ojbect
$view = new View();
$view->import_session_view();
switch($match) {
case 'Show_all':
show_alphabet_list('albums','albums.php','show_all');
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\"><label for=\"match\" accesskey=\"S\">" . _("<u>S</u>how all albums") ."</label> <input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\"></input><input type=\"hidden\" name=\"action\" value=\"match\"></input></form>\n";
$offset_limit = 99999;
$sql = "SELECT id FROM album";
break;
case 'Show_missing_art':
show_alphabet_list('albums','albums.php','show_missing_art');
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\"><label for=\"match\" accesskey=\"S\">" . _("<u>S</u>how all albums") ."</label> <input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\"></input><input type=\"hidden\" name=\"action\" value=\"match\"></input></form>\n";
$offset_limit = 99999;
$sql = "SELECT id FROM album where art is null";
break;
case 'Browse':
case 'show_albums':
show_alphabet_list('albums','albums.php','browse');
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\"><label for=\"match\" accesskey=\"S\">" . _("<u>S</u>how only albums starting with") . "</label> <input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\"></input><input type=\"hidden\" name=\"action\" value=\"match\"></input></form>\n";
$sql = "SELECT id FROM album";
break;
case 'none':
show_alphabet_list('albums','albums.php','a');
echo "<p style=\"font: 10pt bold;\">".
_("Select a starting letter or Show all") . "</p>";
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\"><label for=\"match\" accesskey=\"S\">" . _("<u>S</u>how only albums starting with") . "</label> <input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\"></input><input type=\"hidden\" name=\"action\" value=\"match\"></input></form>\n";
$sql = "SELECT id FROM album WHERE name LIKE 'a%'";
break;
default:
show_alphabet_list('albums','albums.php',$match);
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\"><label for=\"match\" accesskey=\"S\">" . _("<u>S</u>how only albums starting with") . "<input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"$match\"></input><input type=\"hidden\" name=\"action\" value=\"match\"></input></p></form>\n";
echo "<br /><br />";
$sql = "SELECT id FROM album WHERE name LIKE '$match%'";
} // end switch
// if we are returning
if ($_REQUEST['keep_view']) {
$view->initialize();
}
// If we aren't keeping the view then initlize it
elseif ($sql) {
$db_results = mysql_query($sql, dbh());
$total_items = mysql_num_rows($db_results);
if ($match != "Show_all") { $offset_limit = $_SESSION['userdata']['offset_limit']; }
$view = new View($sql, 'albums.php','name',$total_items,$offset_limit);
}
else { $view = false; }
if ($view->base_sql) {
$albums = get_albums($view->sql);
show_albums($albums,$view);
}
} // else no album
echo "<br /><br />";
show_menu_items('Albums');
?>
</body>
</html>

140
amp-mpd.php Normal file
View file

@ -0,0 +1,140 @@
<?php
/*
* nj-jukebox.php - Netjuke MPD-based jukebox.
* Copyright (C) 2003 Benjamin Carlisle (bcarlisle@24oz.com)
* http://mpd.24oz.com/
*
* This has been modified to work with Ampache (http://www.ampache.org) It was
* initially written for NetJuke (http://netjuke.sourceforge.net/)
*
* This program is free software; you can redistribute it 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 more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
require_once("modules/init.php");
// Connect to the MPD
if (!class_exists('mpd')) { require_once(conf('prefix') . "/modules/mpd/mpd.class.php"); }
if (!is_object($myMpd)) { $myMpd = new mpd(conf('mpd_host'),conf('mpd_port')); }
if (!$myMpd->connected) {
echo "<font class=\"error\">" . _("Error Connecting") . ": " . $myMpd->errStr . "</font><br />\n";
log_event($_SESSION['userdata']['username'],' connection_failed ',"Error: Unable able to connect to MPD, " . $myMpd->errStr);
}
else {
switch ($_REQUEST['action']) {
case "add":
if (!$user->has_access(25)) { break; }
$song_ids = array();
$song_ids[0] = $_REQUEST[song_id];
addToPlaylist( $myMpd, $song_ids );
break;
case "rem":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->PLRemove($_REQUEST[id])) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case ' > ':
case "play":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->Play()) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "stop":
case ' X ':
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->Stop()) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case ' = ':
case "pause":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->Pause()) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case '|< ':
case "Prev":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->Previous()) ) echo "ERROR: " . $myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case ' >|';
case "Next":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->Next()) ) echo "ERROR: " . $myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "shuffle":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->PLShuffle()) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "clear":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->PLClear()) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "loop":
if (!$user->has_access(25)) { break; }
if ($_REQUEST['val'] == "On") { $_REQUEST['val'] = '1'; }
else { $_REQUEST['val'] = '0'; }
if ( is_null($myMpd->SetRepeat($_REQUEST['val'])) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "random":
if (!$user->has_access(25)) { break; }
if ($_REQUEST['val'] == "On") { $_REQUEST['val'] = '1'; }
else { $_REQUEST['val'] = '0'; }
if ( is_null($myMpd->SetRandom($_REQUEST['val']))) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "adjvol":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->AdjustVolume($_REQUEST[val])) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "setvol":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->SetVolume($_REQUEST[val])) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "skipto":
if (!$user->has_access(25)) { break; }
if ( is_null($myMpd->SkipTo($_REQUEST[val])) ) echo "ERROR: " .$myMpd->errStr."\n";
header ("Location: " . conf('web_path'));
break;
case "pladd":
if (!$user->has_access(25)) { break; }
$plist = new Playlist( $_REQUEST[pl_id] );
$song_ids = $plist->get_songs();
addToPlaylist( $myMpd, $song_ids );
break;
case "albadd":
if (!$user->has_access(25)) { break; }
$album = new Album( $_REQUEST[alb_id] );
$song_ids = $album->get_song_ids( );
addToPlaylist( $myMpd, $song_ids );
break;
case "show_control":
require (conf('prefix') . "/templates/show_mpdplay.inc");
break;
default:
header ("Location: " . conf('web_path'));
break;
} // end switch
// We're done let's disconnect
$myMpd->Disconnect();
} // end else
?>

126
artists.php Normal file
View file

@ -0,0 +1,126 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
Do most of the dirty work of displaying the mp3 catalog
*/
require_once("modules/init.php");
if (!isset($_REQUEST['match'])) { $_REQUEST['match'] = "Browse"; }
if (!isset($_REQUEST['action'])) { $_REQUEST['action'] = "match"; }
$action = scrub_in($_REQUEST['action']);
show_template('header');
show_menu_items('Artists');
show_clear();
switch($action) {
case 'show':
case 'Show':
show_alphabet_list('artists','artists.php');
$artist = new Artist(scrub_in($_REQUEST['artist']));
$artist->show_albums();
break;
case 'show_all_songs':
$artist = get_artist_name(scrub_in($_REQUEST['artist']));
echo "<h2>" . _("All songs by") . " $artist</h2>";
$song_ids = get_song_ids_from_artist($_REQUEST['artist']);
show_songs($song_ids);
break;
case 'update_from_tags':
$artist = new Artist($_REQUEST['artist']);
echo "<br /><b>" . _("Starting Update from Tags") . ". . .</b><br />\n";
$catalog = new Catalog();
$catalog->update_single_item('artist',$_REQUEST['artist']);
echo "<br /><b>" . _("Update From Tags Complete") . "</b> &nbsp;&nbsp;";
echo "<a href=\"" . conf('web_path') . "/artists.php?action=show&artist=" . $_REQUEST['artist'] . "\">[" . _("Return") . "]</a>";
break;
case 'match':
case 'Match':
$match = scrub_in($_REQUEST['match']);
preg_match("/^(\w*)/", $match, $matches);
show_alphabet_list('artists','artists.php',$match);
if ($match === "Browse") {
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">\n";
echo "<label for=\"match\" accesskey=\"S\">";
echo _("<u>S</u>how artists starting with") . "</label> \n";
echo "<input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\" />\n";
echo "<input type=\"hidden\" name=\"action\" value=\"match\" />\n";
echo "</form>\n";
show_artists();
}
elseif ($match === "Show_all") {
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">\n";
echo "<label for=\"match\" accesskey=\"S\">";
echo _("<u>S</u>how artists starting with") . "</label> ";
echo "<input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\" />\n";
echo "<input type=\"hidden\" name=\"action\" value=\"match\" />\n";
echo "</form>\n";
$_SESSION['view_offset_limit'] = 999999;
show_artists();
}
else {
$chr = preg_replace("/[^a-zA-Z0-9]/", "", $matches[1]);
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">\n";
echo "<label for=\"match\" accesskey=\"S\">";
echo _("<u>S</u>how artists starting with") . "</label> \n";
echo "<input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"$chr\" />\n";
echo "<input type=\"hidden\" name=\"action\" value=\"match\" />\n";
echo "</p></form>\n";
if ($chr == '') {
show_artists('A');
}
else {
show_artists($chr);
}
}
break;
default:
echo "<form name=\"f\" method=\"get\" action=\"".$_SERVER['PHP_SELF']."\">\n";
echo "<label for=\"match\" accesskey=\"S\">";
echo _("<u>S</u>how artists starting with") . "</label> \n";
echo "<input type=\"text\" size=\"3\" id=\"match\" name=\"match\" value=\"\" />\n";
echo "<input type=\"hidden\" name=\"action\" value=\"match\" />\n";
echo "</p></form>\n";
show_alphabet_list('artists','artists.php');
show_artists('A');
break;
}
echo "<br /><br />";
show_menu_items('Artists');
?>
</body>
</html>

71
batch.php Normal file
View file

@ -0,0 +1,71 @@
<?php
/*
Copyright (c) 2004 batch.php by RosenSama
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
creates and sends a zip of an album or playlist
zip is just a container w/ no compression
uses archive.php from
http://phpclasses.mirrors.nyphp.org/browse/file/3191.html
can modify to allow user to select tar, gzip, or bzip2
I believe archive.php requires zlib support to be eanbled
in your PHP build.
*/
require_once('modules/init.php');
require_once(conf('prefix') . "/lib/batch.php");
//test that batch download is permitted (user or system?)
/* Drop the normal Time limit constraints, this can take a while */
set_time_limit(0);
if( batch_ok( ) ) {
switch( scrub_in( $_REQUEST['action'] ) ) {
case "pl":
$id = scrub_in( $_REQUEST['id'] );
$pl = new Playlist( $id );
$name = $pl->name;
$song_ids = $pl->get_songs();
$song_files = get_song_files( $song_ids );
set_memory_limit( $song_files[1]+16 );
send_zip( $name, $song_files[0] );
break;
case "alb":
$id = scrub_in( $_REQUEST['id'] );
$alb = new Album( $id );
$name = $alb->name;
$song_ids = $alb->get_song_ids();
$song_files = get_song_files( $song_ids );
set_memory_limit( $song_files[1]+16 );
send_zip( $name, $song_files[0] );
break;
default:
header( "Location:" . conf('web_path') . "/index.php?amp_error=Unknown action on batch.php: {$_REQUEST['action']}" );
break;
} // action switch
} else { // bulk download permissions
header( "Location: " . conf('web_path') . "/index.php?amp_error=Download disabled" );
} // no bulk download permissions
?>

1
bin/.htaccess Normal file
View file

@ -0,0 +1 @@
Deny from all

80
bin/archive/export_playlist.pl Executable file
View file

@ -0,0 +1,80 @@
#!/usr/bin/perl -w
#
# Exports playlists from ampache
#
# Fill in the site specific database connection parameters below before running
#
use DBI;
# Configure database connection parameters
my $db = "ampache"; # database
my $user = ""; # database user
my $pw = ""; # database user password
if ($#ARGV < 0) {
print "Usage: $0 <filename>\n";
print " Exports Ampache playlists to <filename>.\n";
exit;
}
open(OUT, "> $ARGV[0]") or die("Could not open '$ARGV[0]' for write - $!");
# Build DSNs
my $dsn = "dbi:mysql:database=$db;";
# Connect to database
my $dbh= DBI->connect($dsn, $user, $pw,
{ RaiseError => 1, AutoCommit => 0 });
# Prepare statements
my $sth = $dbh->prepare("SELECT id, name, owner, type FROM playlist");
my $sth2 = $dbh->prepare("SELECT username FROM user
WHERE id = ?");
my $sth3 = $dbh->prepare("SELECT song.file
FROM playlist_data, song
WHERE playlist_data.playlist = ?
AND playlist_data.song = song.id");
# Execute select and loop through results
$sth->execute();
my $count = 0;
my ($id,$name,$owner,$type,$date,$file,$track);
while(($id,$name,$owner,$type) = $sth->fetchrow_array) {
if ($count > 0) {
# Use a blank line as a separator between playlists
print OUT "\n";
}
$count++;
if ($owner =~ /^\d+$/) {
# Fetch username instead of id for owner
$sth2->execute($owner);
$owner = "unknown" unless (($owner) = $sth2->fetchrow_array);
$sth2->finish;
}
# Date is not present in old ampache's
$date = 0 if (! defined($date));
print OUT "Name: $name\n";
print OUT "Owner: $owner\n";
print OUT "Type: $type\n";
# Grab songs for this playlist
$sth3->execute($id);
while(($file) = $sth3->fetchrow_array) {
print OUT "File: $file\n";
}
}
print "Exported $count playlists.\n";
# Clean up
$dbh->disconnect;
close(OUT);

118
bin/archive/import_playlist.pl Executable file
View file

@ -0,0 +1,118 @@
#!/usr/bin/perl -w
#
# Imports playlists into ampache (from export_playlist.pl output)
#
# Fill in the site specific database connection parameters below before running
#
use DBI;
use Data::Dumper;
# Configure database connection parameters
my $db = "ampache3_1"; # database
my $user = ""; # database user
my $pw = ""; # database user password
if ($#ARGV < 0) {
print "Usage: $0 <filename>\n";
print " Imports Ampache playlists from <filename>.\n";
print " The format of <filename> should match the output of export_playlist.pl.\n";
exit;
}
open(IN, "$ARGV[0]") or die("Could not open '$ARGV[0]' for read - $!");
# Build DSNs
my $dsn = "dbi:mysql:database=$db;";
# Connect to database
my $dbh = DBI->connect($dsn, $user, $pw,
{ RaiseError => 1, AutoCommit => 0 });
# Structure to contain playlists
my @playlists;
# Parse file
my $i = 0;
while($line = <IN>) {
chomp $line;
if ($line eq "") {
# Blank line means new playlist
$i++;
next;
}
if ($line =~ /^ID: (.*)$/) {
$playlists[$i]->{id} = $1;
}
if ($line =~ /^Name: (.*)$/) {
$playlists[$i]->{name} = $1;
}
if ($line =~ /^Owner: (.*)$/) {
$playlists[$i]->{owner} = $1;
}
if ($line =~ /^Type: (.*)$/) {
$playlists[$i]->{type} = $1;
}
if ($line =~ /^File: (.*)$/) {
push @{$playlists[$i]->{files}}, $1;
}
}
close(IN);
# Prepare statements
my $sth = $dbh->prepare("SELECT id FROM user
WHERE username = ?");
my $sth2 = $dbh->prepare("INSERT INTO playlist
(name, owner, type)
values (?, ?, ?)");
my $sth3 = $dbh->prepare("SELECT id FROM song
WHERE file = ?");
my $sth4 = $dbh->prepare("INSERT INTO playlist_data
(playlist, song, track)
values (?, ?, ?)");
# Insert records into Ampache
my ($id,$name,$owner,$type,$file,$songid);
my $count = 0;
for ($i = 0; $i < $#playlists + 1; $i++) {
$count++;
$name = $playlists[$i]->{name};
$sth->execute($playlists[$i]->{owner});
$owner = 0 unless (($owner) = $sth->fetchrow_array);
$sth->finish;
$type = $playlists[$i]->{type};
print "Importing playlist '$name'...\n";
# Create base playlist entry
$sth2->execute($name, $owner, $type);
$id = $dbh->{mysql_insertid};
# And add files to it
while($file = pop(@{$playlists[$i]->{files}})) {
$sth3->execute($file);
next unless (($songid) = $sth3->fetchrow_array);
$sth3->finish;
$sth4->execute($id,$songid,0);
}
}
print "Imported $count playlists.\n";
# Clean up
$dbh->disconnect;
close(IN);

56
bin/archive/migrate_user.pl Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/perl -w
#
# Migrates users from Ampache v3.0 to Ampache v3.1.
#
# Fill in the site specific database connection parameters below before running
#
use DBI;
# Configure database connection parameters
my $db_old = "ampache"; # old database
my $db_new = "ampache3_1"; # new database
my $user_old = ""; # old database user
my $user_new = ""; # new database user
my $pw_old = "!"; # old database user password
my $pw_new = "!"; # new database user password
# Build DSNs
my $dsn_new = "dbi:mysql:database=$db_new;";
my $dsn_old = "dbi:mysql:database=$db_old;";
# Connect to old and new databases
my $dbh_new = DBI->connect($dsn_new, $user_new, $pw_new,
{ RaiseError => 1, AutoCommit => 0 });
my $dbh_old = DBI->connect($dsn_old, $user_old, $pw_old,
{ RaiseError => 1, AutoCommit => 0 });
# Prepare select and insert statements
my $sth = $dbh_old->prepare("SELECT username, fullname, email, password, access
FROM user");
my $sth_update = $dbh_new->prepare("INSERT INTO user
(username, fullname, email, password, access, offset_limit)
VALUES (?, ?, ?, ?, ?, 50)");
# Execute select and loop through results
$sth->execute();
my ($f1,$f2,$f3,$f4,$f5);
my $count = 0;
while(($f1,$f2,$f3,$f4,$f5) = $sth->fetchrow_array) {
$sth_update->execute($f1,$f2,$f3,$f4,$f5);
$count++;
}
print "Migrated $count users.\n";
# Clean up
$dbh_old->disconnect;
$dbh_new->disconnect;

View file

@ -0,0 +1,18 @@
<?php
$no_session='1';
require ("../modules/init.php");
$sql = "SELECT id FROM catalog WHERE catalog_type='local'";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_row($db_results)) {
$catalog = new Catalog($r[0]);
// Verify Existing
$catalog->verify_catalog();
// Look for new files
$catalog->add_to_catalog();
}
?>

View file

@ -0,0 +1,55 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
$no_session = '1';
require ("../modules/init.php");
require ("../lib/debug.php");
$results = debug_read_config(conf('prefix') . "/config/ampache.cfg.php");
$dist_results = debug_read_config(conf('prefix') . "/config/ampache.cfg.php.dist");
echo "\nCHECKING CONF VARS... \n\n";
foreach ($dist_results['conf'] as $key=>$value) {
if (!isset($results['conf'][$key])) {
echo "MISSING:";
echo " $key = $value\n";
}
} // foreach dist
echo "\nCHECKING LIBGLUE VARS...\n\n";
foreach ($dist_results['libglue'] as $key=>$value) {
if (!isset($results['libglue'][$key])) {
echo "MISSING:";
echo " $key = $value\n";
}
} // foreach libglue
?>

32
bin/create_genre Executable file
View file

@ -0,0 +1,32 @@
#!/usr/bin/perl
# Copyright (c) 2000 Kveton.com
# All rights reserved.
# $Id: create_genre,v 1.2 2003/11/24 05:53:12 vollmerk Exp $
# $Source: /data/cvsroot/ampache/bin/create_genre,v $
# Create the genres in the database for ease of use
use DBI;
# User, pass and database names
my $user = '_user_';
my $pass = '_password_';
my $db_name = 'ampache';
my $db_host = 'localhost';
$dbh = DBI->connect("dbi:mysql:database=$db_name;host=$db_host;port=3306", $user, $pass);
my $sql = qq{INSERT INTO genre (id,name) VALUES (?,?)};
my $sth = $dbh->prepare($sql);
open(GENRE, "< genres.txt");
while ( $line = <GENRE> ) {
chomp $line;
my ($id, $name) = split(/\./, $line);
print "$id : $name\n";
$sth->execute($id,$name);
}
1;

29
bin/filesort.pl Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/perl -w
#
# Sorts your MP3s into directories based on the sort pattern specified
# in ampache
use FindBind qw($Bin);
require "$Bin/init";
use Data::Dumper;
use Getopt::Long;
Getopt::Long::Configure('bundling','no_ignore_case');
GetOptions
("h|help" => \$usage,
"t|test" => \$pretend,
"a|all" => \$all,
"s|sort" => \$sort,
"c|clean" => \$clean,
"v|verbose" => \$verbose);
if ($help) {
usage();
}
#
# Pull in Data from Ampache
#

346
bin/fileupdate.pl Executable file
View file

@ -0,0 +1,346 @@
#!/usr/bin/perl -w
# Find and file away MP3's. Run multiple times and will
# ignore addition of duplicates in db (based on MD5 hash
# of full file path.
use FindBin qw($Bin);
require "$Bin/init";
use Data::Dumper;
use Getopt::Long;
use vars qw($help $pretend $id3 $rename $sort $all $verbose);
Getopt::Long::Configure('bundling','no_ignore_case');
GetOptions
("h|help" => \&usage,
"p|pretend" => \$pretend,
"i|id3" => \$id3,
"r|rename" => \$rename,
"s|sort" => \$sort,
"a|all" => \$all,
"rename_all" => \$rename_all,
"sort_all" => \$sort_all,
"v|verbose" => \$verbose);
if ( !$help && !$all && !$id3 && !$rename && !$sort && !$rename_all && !$sort_all ) {
usage();
}
if ($help) {
usage();
}
if($id3 or $all)
{
my @flagged = $ampache->get_table_where("flagged","WHERE type = 'setid3'");
foreach my $update(@flagged)
{
my @info = $ampache->get_song_info($update->{'song'});
my $cmd = update_id3_tag($ampache,@info);
if($rename or $all)
{
if($verbose){ print "Marking for rename after id3\n"; }
if(!$pretend){ $ampache->change_flags(@info,'setid3','ren'); }
}
else
{
if($sort or $all)
{
if($verbose){ print "Marking for sort after id3\n"; }
if(!$pretend){ $ampache->change_flags(@info,'setid3','sort'); }
}
else
{
if($verbose){ print "Stopping after id3 update\n"; }
if(!$pretend){ $ampache->change_flags(@info,'setid3','notify'); }
}
}
}
}
if($rename or $all)
{
my $filename = '';
my @flagged = $ampache->get_table_where("flagged","WHERE type = 'ren'");
foreach my $update (@flagged)
{
my @info = $ampache->get_song_info($update->{'song'});
my $cmd = rename_file($ampache,\$filename,@info);
if(!$pretend){ $ampache->update_song($cmd,@info); }
if($sort or $all)
{
if($verbose){ print "Marking for sort after rename\n"; }
if(!$pretend){ $ampache->change_flags(@info,'ren','sort'); }
}
else
{
if($verbose){ print "Updating filename in DB after rename\n"; }
if(!$pretend){ $ampache->change_flags(@info,'ren','notify'); }
}
}
}
if ($rename_all) {
my $filename = '';
my @flagged = $ampache->get_table_where("catalog,song","WHERE catalog.catalog_type='local' AND catalog.id=song.catalog","song.id AS song");
foreach my $update (@flagged) {
my @info = $ampache->get_song_info($update->{'song'});
my $cmd = rename_file($ampache,\$filename,@info);
if(!$pretend){ $ampache->update_song($cmd,@info); }
} # End Foreach
} # End Rename All
if ($sort_all) {
my $filename = '';
my @flagged = $ampache->get_table_where("catalog,song","WHERE catalog.catalog_type='local' AND catalog.id=song.catalog","song.id AS song");
foreach my $update(@flagged)
{
my @info = $ampache->get_song_info($update->{'song'});
my $cmd = sort_file($ampache,\$filename,@info);
if(!$pretend){ $ampache->update_song($cmd,@info); }
if($verbose){ print "Updating filename in DB after sort\n"; }
if(!$pretend){ $ampache->change_flags(@info,'sort','notify'); }
}
} # End Sort ALL
if($sort or $all)
{
my $filename = '';
my @flagged = $ampache->get_table_where("flagged","WHERE type = 'sort'");
foreach my $update(@flagged)
{
my @info = $ampache->get_song_info($update->{'song'});
my $cmd = sort_file($ampache,\$filename,@info);
if(!$pretend){ $ampache->update_song($cmd,@info); }
if($verbose){ print "Updating filename in DB after sort\n"; }
if(!$pretend){ $ampache->change_flags(@info,'sort','notify'); }
}
}
# # # # #
# subs
# # # # # # #
# %A = album name
# %a = artist name
# %C = catalog path (for the specified song)
# %c = comment
# %g = genre
# %y = year
# %T = track number
# %t = song title
#
# %filename I use for filename
sub get_catalog_setting
{
my ($self,$catalog,$setting) = @_;
#bless $self;
my $cmd = $self->get_catalog_option($catalog,$setting);
return $cmd;
}
sub update_id3_tag
{
my ($self,$song) = @_;
my $id3set = get_catalog_setting($self,$song->{'catalog'},'id3_set_command');
$id3set =~ s/\Q%A\E/$song->{'album'}/g;
$id3set =~ s/\Q%a\E/$song->{'artist'}/g;
$id3set =~ s/\Q%C\E/$song->{'catalog'}/g;
$id3set =~ s/\Q%c\E/$song->{'comment'}/g;
if(($song->{'genre'} * 1) < 255){$id3set =~ s/\Q%g\E/$song->{'genre'}/g;}
else{$id3set =~ s/ -g %g//g;}
$id3set =~ s/\Q%T\E/$song->{'track'}/g;
$id3set =~ s/\Q%t\E/$song->{'title'}/g;
$id3set =~ s/\Q%y\E/$song->{'year'}/g;
$id3set =~ s/\Q%filename\E//g;
# $id3set =~ s/([\'\"])/\\$1/g;
my $filename = $song->{'file'};
my $id3tag_command = "$id3set \"$filename\"";
return do_call($id3tag_command);
}
sub rename_file
{
my ($self,$filename,$song) = @_;
my $ren_pattern = get_catalog_setting($self,$song->{'catalog'},'rename_pattern');
#my $sort_pattern = get_catalog_setting($self,$song->{'catalog'},'sort_pattern');
my $basedir;
if( $song->{'file'} =~ m/^(.*)\/.*?$/ )
{
$basedir = $1;
}
else{ die "Could not determine base directory for $song->{'file'}\n"; }
# We want to pad track numbers with leading zeros:
if($song->{'track'} < 10)
{
$song->{'track'} = "0".$song->{'track'};
}
# we need to clean title,album,artist,comment,genre,track, and year
$song->{'title'} =~ s/[\/]/-/g;
$song->{'album'} =~ s/[\/]/-/g;
$song->{'artist'} =~ s/[\/]/-/g;
$song->{'comment'} =~ s/[\/]/-/g;
$song->{'genre'} =~ s/[\/]/-/g;
$song->{'track'} =~ s/[\/]/-/g;
$song->{'year'} =~ s/[\/]/-/g;
$ren_pattern =~ s/\Q%A\E/$song->{'album'}/g;
$ren_pattern =~ s/\Q%a\E/$song->{'artist'}/g;
$ren_pattern =~ s/\Q%C\E/$song->{'catalog'}/g;
$ren_pattern =~ s/\Q%c\E/$song->{'comment'}/g;
$ren_pattern =~ s/\Q%g\E/$song->{'genre'}/g;
$ren_pattern =~ s/\Q%T\E/$song->{'track'}/g;
$ren_pattern =~ s/\Q%t\E/$song->{'title'}/g;
$ren_pattern =~ s/\Q%y\E/$song->{'year'}/g;
$ren_pattern =~ s/\Q%filename\E/$song->{'file'}/g;
my $oldfilename = $song->{'file'};
my $newfilename = $basedir . "/" . $ren_pattern;
# result is backslashes in filename
# $newfilename =~ s/([\'\"])/\\$1/g;
print "\tNew: $newfilename -- OLD: $oldfilename\n";
if(! -e "$newfilename")
{
my $ren_command = "mv \"$oldfilename\" \"$newfilename\"";
$filename = $newfilename;
do_call($ren_command);
return $filename;
}
else
{
print STDERR "File exists: $newfilename\n";
$filename = $oldfilename;
return $filename;
}
}
sub sort_file
{
my ($self, $filename, $song) = @_;
my $basename;
my $basedir;
if( $song->{'file'} =~ m/^(.*)\/(.*?)$/ )
{
$basename = $2;
$basedir = $1
}
else{ die "Could not determine base name for $song->{'file'}\n"; }
# we need to clean title,album,artist,comment,genre,track, and year
$song->{'title'} =~ s/[\/]/-/g;
$song->{'album'} =~ s/[\/]/-/g;
$song->{'artist'} =~ s/[\/]/-/g;
$song->{'comment'} =~ s/[\/]/-/g;
$song->{'genre'} =~ s/[\/]/-/g;
$song->{'track'} =~ s/[\/]/-/g;
$song->{'year'} =~ s/[\/]/-/g;
my $location = get_catalog_setting($self,$song->{'catalog'},'sort_pattern');
$location =~ s/\Q%A\E/$song->{'album'}/g;
$location =~ s/\Q%a\E/$song->{'artist'}/g;
$location =~ s/\Q%C\E/$song->{'catalog'}/g;
$location =~ s/\Q%c\E/$song->{'comment'}/g;
$location =~ s/\Q%g\E/$song->{'genre'}/g;
$location =~ s/\Q%T\E/$song->{'track'}/g;
$location =~ s/\Q%t\E/$song->{'title'}/g;
$location =~ s/\Q%y\E/$song->{'year'}/g;
# result is wrong paths
# $location =~ s/([\'\"])/\\$1/g;
create($location);
# The basename is calculated so we can see if the file already exists
if(! -e "$location/$basename")
{
my $cmd = "/bin/mv \"".$song->{'file'}."\" \"$location\"";
my $ret = do_call($cmd);
if(empty_dir($basedir))
{
print "Removing empty directory $basedir\n";
$cmd = "/bin/rmdir \"$basedir\"";
do_call($cmd);
}
$filename = $location."/".$basename;
return $filename;
}
else
{
print STDERR "File exists: $location/$basename\n";
$filename = $song->{'file'};
return $filename;
}
}
sub usage
{
my $usage = qq{
fileupdate [--id3|--rename|--rename_all|--sort|--sort_all|--all] [--help] [--pretend] [--verbose]
--pretend Display command taken, without actually doing anything.
--id3 Update id3 tags for all files flagged with 'id3'
--rename Rename files flagged with 'rename'
--rename_all Renames all files based on id3 info
--sort Sort files flagged with 'sort'
--sort_all Sort all files based on id3 info
--all Performs id3 update, rename, and sort
for all files flagged with 'id3'
--verbose Shows detailed information about what's happening.
--help This message
};
die $usage;
}
sub do_call
{
my @cmd = @_;
my $return = 0;
if($verbose && !$pretend){ print "@cmd\n";}
if($pretend){ print "@cmd\n"; }
else
{
$return = system @cmd;
}
return $return;
}
sub create
{
my ($path) = @_;
if(! -e $path)
{
return do_call("mkdir","-p",$path);
}
return 1;
}
# empty_dir borrowed from Tom Phoenix (rootbeer@teleport.com)
# posted in comp.lang.perl.misc on 3/21/97
sub empty_dir ($)
{
local(*DIR, $_);
return unless opendir DIR, $_[0];
while (defined($_ = readdir DIR)) {
next if /^\.\.?$/;
closedir DIR;
return 0;
}
closedir DIR;
1;
}
1;

148
bin/genres.txt Executable file
View file

@ -0,0 +1,148 @@
1.Classic Rock
2.Country
3.Dance
4.Disco
5.Funk
6.Grunge
7.Hip-Hop
8.Jazz
9.Metal
10.New Age
11.Oldies
12.Other
13.Pop
14.R&B
15.Rap
16.Reggae
17.Rock
18.Techno
19.Industrial
20.Alternative
21.Ska
22.Death Metal
23.Pranks
24.Soundtrack
25.Euro-Techno
26.Ambient
27.Trip-Hop
28.Vocal
29.Jazz+Funk
30.Fusion
31.Trance
32.Classical
33.Instrumental
34.Acid
35.House
36.Game
37.Sound Clip
38.Gospel
39.Noise
40.AlternRock
41.Bass
42.Soul
43.Punk
44.Space
45.Meditative
46.Instrumental Pop
47.Instrumental Rock
48.Ethnic
49.Gothic
50.Darkwave
51.Techno-Industrial
52.Electronic
53.Pop-Folk
54.Eurodance
55.Dream
56.Southern Rock
57.Comedy
58.Cult
59.Gangsta
60.Top 40
61.Christian Rap
62.Pop/Funk
63.Jungle
64.Native American
65.Cabaret
66.New Wave
67.Psychadelic
68.Rave
69.Showtunes
70.Trailer
71.Lo-Fi
72.Tribal
73.Acid Punk
74.Acid Jazz
75.Polka
76.Retro
77.Musical
78.Rock & Roll
79.Hard Rock
80.Folk
81.Folk-Rock
82.National Folk
83.Swing
84.Fast Fusion
85.Bebob
86.Latin
87.Revival
88.Celtic
89.Bluegrass
90.Avantgarde
91.Gothic Rock
92.Progressive Rock
93.Psychedelic Rock
94.Symphonic Rock
95.Slow Rock
96.Big Band
97.Chorus
98.Easy Listening
99.Acoustic
100.Humour
101.Speech
102.Chanson
103.Opera
104.Chamber Music
105.Sonata
106.Symphony
107.Booty Bass
108.Primus
109.Porn Groove
110.Satire
111.Slow Jam
112.Club
113.Tango
114.Samba
115.Folklore
116.Ballad
117.Power Ballad
118.Rhythmic Soul
119.Freestyle
120.Duet
121.Punk Rock
122.Drum Solo
123.A capella
124.Euro-House
125.Dance Hall
126.Goa
127.Drum & Bass
128.Club-House
129.Hardcore
130.Terror
131.Indie
132.BritPop
133.Negerpunk
134.Polsk Punk
135.Beat
136.Christian Gansta Rap
137.Heavy Metal
138.Black Metal
139.Crossover
140.Contemporary Christian
141.Christian Rock
142.Merengue
143.Salsa
144.Thrash Metal
145.Anime
146.JPop
147.Synthpop
255.Unknown

11
bin/init Executable file
View file

@ -0,0 +1,11 @@
#! /usr/bin/perl
# Copyleft Ampache.org
# This script loads up the path to the perl module
#
use FindBin qw($Bin);
use lib "$Bin/../lib/perl/Local/Ampache/blib/lib";
use Local::Ampache;
$ampache = new Local::Ampache("$Bin/..");

6
bin/moosic Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/python
import sys
from moosic.client.cli.main import main
main(sys.argv)

6
bin/moosicd Executable file
View file

@ -0,0 +1,6 @@
#!/usr/bin/python
import sys
from moosic.server.main import main
main(sys.argv)

47
bin/parse_m3u.php.inc Normal file
View file

@ -0,0 +1,47 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Name of the filename who's tags you want to read */
$filename = "/data/music/Live/L/Life'll Kill Ya/Warren Zevon.m3u";
$no_session = '1';
require ("../modules/init.php");
$handle = fopen($filename,'r');
$data = fread($handle,filesize($filename));
$results = explode("\n",$data);
foreach ($results as $value) {
$value = trim($value);
if (preg_match("/\.[A-Za-z0-9]{3}$/",$value)) {
echo "$value \n";
$sql = "SELECT id FROM song WHERE file LIKE '%" . sql_escape($value) . "'";
$db_results = mysql_query($sql, dbh());
$foo = mysql_result($db_results,'id');
echo "\t Results: " . $foo . "\n";
print_r($foo);
}
} // end foreach
?>

42
bin/print_amazon.php.inc Executable file
View file

@ -0,0 +1,42 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Name of the filename who's tags you want to read */
$search['album_name'] = "Ariels";
$search['artist_name'] = "Bent";
$no_session = '1';
require ("../modules/init.php");
echo "<pre>\n";
$amazon = new AmazonSearch(conf('amazon_developer_key'));
// Prevent the script from timing out
set_time_limit(0);
$search_term = $search['artist_name'] . " " . $search['album_name'];
$amazon->search(array('artist' => $search['artist_name'], 'album' => $search['album_name'], 'keywords' => $serch_term));
$amazon->lookup($amazon->results);
echo "Search Term: $search_term\n";
echo "Artist: " . $search['artist_name'] . " AND Album: " . $search['album_name'] . "\n";
print_r($amazon->results);
echo "\n</pre>";
?>

34
bin/print_tags.php.inc Normal file
View file

@ -0,0 +1,34 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Name of the filename who's tags you want to read */
$filename = "/data/music/Upload/woo.spx";
$no_session = '1';
require ("../modules/init.php");
echo "<pre>";
$info = new Audioinfo();
$results = $info->info($filename);
print_r($results);
?>

1
config/.htaccess Normal file
View file

@ -0,0 +1 @@
Deny from all

461
config/ampache.cfg.php.dist Normal file
View file

@ -0,0 +1,461 @@
##<?php exit(); ?>##
####################
# General Config
####################
[conf]
####################
####################
# Path Vars
####################
# The path to your ampache install
# Do not put a trailing / on this path
# For example if your site is located at http://localhost
# than you do not need to enter anything for the web_path
# if it is located at http://localhost/music you need to
# set web_path to /music
# DEFAULT: ""
#web_path = ""
# Lang (define the locale you want to use
# this is a cheeseball fix for now it will be smarter
# later.
# DEFAULT: en_US
#lang = "en_US"
####################
# The libglue Vars #
####################
[libglue]
####################
###
# Below are the variables for the Local Database that will do Auth
###
# Hostname of your Database (default is localhost)
# DEFAULT: localhost
local_host = localhost
# Name of your ampache database (default is ampache)
# DEFAULT: ampache
local_db = ampache
# Username for your ampache database
# DEFAULT: ""
local_username = username
# Password for your ampache database (can't be blank!)
# DEFAULT: ""
local_pass = password
# Login Length in seconds for local logins
# DEFAULT: 900
local_length = 900
# This is the DOMAIN for the cookie that stores your session key
# this must be set to the domain of your host or you will not be
# able to log in make sure you including the leading .
# This is not needed unless you are using libglue for more than one
# website, and you are using SSO
# DEFAULT: ""
#sess_domain = .yourwebsite.com
# Name of the Session/Cookie that will sent to the browser
# default should be fine
# DEFAULT: ampache
sess_name = ampache
# Lifetime of the Cookie, 0 == Forever (until browser close) , otherwise in terms of seconds
# DEFAULT: 0
sess_cookielife = 0
# Is the cookie a "secure" cookie?
# DEFAULT: 0
sess_cookiesecure = 0
# Path your copy of libglue (Included with Ampache)
# Uncomment this if you have moved libglue to a non-standard location
# DEFAULT: /libglue
#libglue_path = "/libglue"
# Pre-Defined Error messages
# you should not need to edit these
empty_field = "You left one or more fields empty. Please enter both your username and password to log in."
bad_auth_cred = "Unable to authenticate using this service: This is most likely a configuration mistake by the site administrator."
user_not_found = "Username not found."
login_failed = "Bad username or password."
connect_error = "Could not connect to authentication server."
####################
# The conf vars! #
####################
[conf]
####################
# Nuff Said
# DEFAULT: Ampache :: For The Love of Music
site_title = "Ampache :: For The Love Of Music"
# Use Access List
# Toggle this on if you want ampache to pay attention to the access list
# and only allow streaming/downloading/xml-rpc from known hosts by default
# xml-rpc will not working without this on.
# DEFAULT: false
#access_control = "false"
# Require Session
# If this is set to true ampache will make sure that the URL passed when
# attempting to retrive a song contains a valid Session ID This prevents
# others from guessing URL's
# DEFAULT: true
require_session = "true"
# Use XML-RPC
# Allow XML-RPC connections, if you don't want _any_ possibility of your
# catalog being streamed from another location comment this out
# DEFAULT: false
#xml_rpc = "false"
# 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
# want to be able to use this function
# DEFAULT: false
#allow_zip_download = "false"
# This setting turns on/off public registration. It is
# recommended you leave this off, as it will allow anyone to
# sign up for an account on your server.
# DEFAULT: false
# THIS IS CURRENTLY BROKEN!
#allow_public_registration = "false"
# This sets which ID3 tag takes precedence.
# we've found for those of you who don't have
# good v2 tags it's sometimes nice to keep the v1
# until you've fixed v2
# POSSIBLE VALUES: id3v1 id3v2
# DEFAULT: id3v2,id3v1
id3tag_order = "id3v2"
id3tag_order = "id3v1"
# Un comment if don't want ampache to follow symlinks
# DEFAULT: false
#no_symlinks = "false"
# Use auth?
# If this is set to "Yes" ampache will require a valid
# Username and password. If this is set to no then ampache
# will not ask you for a username and password. No is only
# recommended for internal only instances
# DEFAULT true
use_auth = "yes"
# This options will turn on/off Demo Mode
# If Demo mode is on you can not play songs or update your catalog
# in other words.. leave this commented out
# DEFAULT: false
#demo_mode = "false"
# Memory Limit
# This defines the "Min" memory limit for PHP if your php.ini
# has a lower value set Ampache will set it up to this. If you
# set it below 16MB getid3() will not work!
# DEFAULT: 16
#memory_limit = 16
# Album Art Preferred Filename
# Specify a filename to look for if you always give the same filename
# i.e. "folder.jpg" Ampache currently only supports jpg/gif and png
# Especially useful if you have a front and a back image in a folder
# comment out if ampache should search for any jpg,gif or png
# DEFAULT: folder.jpg
#album_art_preferred_filename = "folder.jpg"
# Album Art Gather Order
# Simply arrange the following in the order you would like
# ampache to search if you want to disable one of the search
# method simply comment it out valid values are
# POSSIBLE VALUES: id3 folder amazon
# DEFAULT: id3,folder,amazon
album_art_order = "id3"
album_art_order = "folder"
album_art_order = "amazon"
# Album Art in Now Playing
# Set this to true if you want the now playing box to display
# album art from said album
# DEFAULT: true
play_album_art = "true"
# Amazon Developer Key
# This is needed in order to actually use the amazon album art
# DEFAULT: false
#amazon_developer_key = ""
# Debug
# If this is enabled Ampache will get really chatty
# warning this can crash browser during catalog builds due to
# the amount of text that is dummped out this will also cause
# ampache to write to the log file
# DEFAULT: false
#debug = "false"
# Path to Log File
# This defines where you want ampache to log events to
# this will only happen if debug is turned on. Do not
# include trailing slash. Default is /tmp
# DEFAULT: /tmp
#log_path = "/tmp"
# Max Upload Size
# This sets what the max filesize for an uploaded
# file, this is good at preventing someone from
# filling up your HDD. It is mesured in bytes
# Example 1024 = 1K, 1048576 = 1MB
# Default size limit is 10Mb
# DEFAULT: 10485760
max_upload_size = "10485760"
# Charset of generated HTML pages
# Default of iso-8859-1 should work for most poeple
# DEFAULT: iso-8859-1
site_charset = iso-8859-1
##########################################################
# These Option Control which playback methods are allowed
##########################################################
# Stream Playback
# Disable this if you don't want to allow people to stream
# using HTTP without downsampling
# DEFAULT: true
allow_stream_playback = true
# Downsampling Playback
# Disable this if you don't want to allow people to downsample
# songs before they are streamed
# DEFAULT: false
#allow_downsample_playback = false
# LocalPlay Playback
# Disable this if you don't want to allow people to pick the
# local playback method
# DEFAULT: false
#allow_local_playback = false
# MPD Playback
# Disable this if you don't want to allow people to push things
# to a MPD server as defined below
# DEFAULT: false
#allow_mpd_playback = false
# Icecast Playback
# Disable this if you don't have an IceCast server to push
# music to
# DEFAULT: false
#allow_icecast_playback = false
# Slim Server Playback
# Disable this if you don't have a SlimServer to push music
# to
# DEFAULT: false
#allow_slim_playback = false
#######################################################
# These options control how searching works
#######################################################
# choices are: artist,album,song_title,song_genre,song_year,song_bitrate,song_min_bitrate,song_filename
# DEFAULT: song_title
search_field = song_title
# choices are: exact,fuzzy
# DEFAULT: fuzzy
search_type = fuzzy
#######################################################
# This option controls what Ampache sends for the Stream name. This
# is most valuable when then 'Type of Playback' is set to downsample.
# because lame seems to strip id3 tags. if you want the Ampache default
# just leave this option commented out.
#
# the format supports the followning options:
#
# %A = album name
# %a = artist name
# %C = catalog path
# %c = id3 comment
# %g = genre
# %T = track number
# %t = song title
# %y = year
# %basename = current filename (just the actual filename)
# %catalog = catalog name
# %filename = current filename (full path)
# %type = song type (mp3, ogg, ...)
#
# DEFAULT: %a - %A - %t
#stream_name_format = %a - %A - %t
#######################################################
# These options control the down-sampling feature
# this requires you to install some applications such
# as lame that can re-encode the mp3 for you.
# we recommend mp3splt and lame
# %FILE% = filename
# %OFFSET% = offset
# %SAMPLE% = sample rate
# %EOF% = end of file in min.sec
# DEFAULT: mp3splt -qnf "%FILE%" %OFFSET% %EOF% -o - | lame --mp3input -q 3 -b %SAMPLE% -S - -
downsample_cmd = mp3splt -qnf "%FILE%" %OFFSET% %EOF% -o - | lame --mp3input -q 3 -b %SAMPLE% -S - -
#######################################################
# These options control the "local play" feature. This requires
# a playlist manager such as moosic, winamp, xmms etc which
# can be controlled via command line.
# The defaults below are for moosic, a python based music
# player daemon. You must currently start the daemon
# yourself, because it doesn't fork right for launch
# inside apache.
# Valid replacements are:
# %URL% = url to the song
# %AMOUNT% = amount to increase or decrese the volume by (optional)
#
# HACK altert - run moosicd as www-data user, and
# then set the HOME env var so moosic client
# can find the folder it needs b4 every call...
# Commenting this all out, unless you uncomment it...
### ADD - add song to playlist
# DEFAULT: export HOME='/var/www'; moosic -n add %URL%
#localplay_add = "export HOME='/var/www'; moosic -n add %URL%"
### STOP - stop the playback.
# DEFAULT: export HOME='/var/www'; moosic stop
#localplay_stop = "export HOME='/var/www'; moosic stop"
### PLAY - begin stopped or paused playback.
# DEFAULT: export HOME='/var/www'; moosic play
#localplay_play = "export HOME='/var/www'; moosic play"
### PAUSE - pause the player
# DEFAULT: export HOME='/var/www'; moosic pause
#localplay_pause = "export HOME='/var/www'; moosic pause"
### NEXT - Skip to the next song in the list
# DEFAULT: export HOME='/var/www'; moosic next
#localplay_next = "export HOME='/var/www'; moosic next"
### PREV - Skip to the next song in the list
# DEFAULT: export HOME='/var/www'; moosic previous
#localplay_prev = "export HOME='/var/www'; moosic previous"
### VOLUME UP - increase the volume
# DEFAULT: amixer -q set Master %AMOUNT%%+
#localplay_volplus = "amixer -q set Master %AMOUNT%%+"
### VOLUME DOWN - decrease the volume
# DEFAULT: amixer -q set Master %AMOUNT%%-
#localplay_volminus = "amixer -q set Master %AMOUNT%%-"
### START - NOT USED - strt the player daemon.
# DEFAULT: export HOME='/var/www'; moosicd &
#localplay_start = "export HOME='/var/www'; moosicd &"
### CLEAR - remove all from playlist and stop playing.
# DEFAULT: export HOME='/var/www'; moosic wipe
#localplay_clear = "export HOME='/var/www'; moosic wipe"
### KILL - stop the player daemon
# DEFAULT: export HOME='/var/www'; moosic die
#localplay_kill = "export HOME='/var/www'; moosic die"
### This must return a 1 line "status report" which is
### displayed under the player controls.
# DEFAULT: export HOME='/var/www'; moosic state|grep 'items in the'
#localplay_status = "export HOME='/var/www'; moosic state|grep 'items in the'"
#######################################################
# these options allow you to configure your rss-feed
# layout. rss exists of two parts, main and song
# main is the information about the feed
# song is the information in the feed. can be multiple
# items.
#
#
# rss_main_title = the title for your feed.
# DEFAULT: Ampache for the love of Music
rss_main_title = Ampache for the love of Music
# rss_main_description = the description for your feed
# DEFAULT: Rss feed for Ampache so you can monitor who is listening to what
rss_main_description = Rss feed for Ampache so you can monitor who is listening to what
# rss_main_copyright = here you can enter copyright information if you wish
# DEFAULT: copyright (c) Speedy B for Ampache
rss_main_copyright = copyright (c) Speedy B for Ampache
# rss_main_language = the feed language. Some feed readers use this.
# DEFAULT: nl
rss_main_language = nl
# rss_song_description = The description of the song.
# It has to start with <![CDATA[
# and end with ]]>. this is because xml wont parse if strange
# characters are used in the id3-tag
# usable items:
# $song->f_title
# $song->f_album
# $user->fullname
# $artist
# $album
# DEFAULT: <![CDATA[$song->f_title @ $album played by $user->fullname]]>
rss_song_description = <![CDATA[$song->f_title @ $album played by $user->fullname]]>
######################################################
#######################
# ICECAST2 Settings #
#######################
# These settings are for the ICECAST2 support
# built into Ampache.
######################################################
# Tracklist Filename
# This defines the file that the tracklist
# for icecast is written to, this file must
# be writeable by the web server process
# DEFAULT: /tmp/tracklist.txt
#icecast_tracklist = "/tmp/tracklist.txt"
# Icecast Command
# This is the command that is run when ampache
# attempts to start up icecast. %FILE% represents
# the icecast_tracklist variable (Filename)
# DEFAULT: /usr/local/bin/ices -c /usr/local/etc/ices.conf -F %FILE% -B
#icecast_command = "/usr/local/bin/ices -c /usr/local/etc/ices.conf -F %FILE% -B"
#####################################################
###################
# MPD Settings #
###################
# These settings are for the MPD support
# built into Ampache.
#####################################################
# MPD Port
# This defines which port that ampache attempts to
# connect to MPD on.
# DEFAULT: 6600
#mpd_port = "6600"
# MPD Hostname
# This is the hostname of the computer running MPD
# DEFAULT: localhost
#mpd_host = "localhost"
# MPD Password
# This is the password for the MPD server
# DEFAULT: ""
#mpd_pass = ""
# MPD Method
# This is the method you want to use to pass your
# music to your MPD player. Possible values are
# file and url. I highly recommend using the URL
# method as it requires less configuration.
# POSSIBLE VALUES: file url
# DEFAULT: file
#mpd_method = "file"
#####################################################

View file

@ -0,0 +1,247 @@
####################
# Hauptkonfiguration
####################
[conf]
####################
####################
# Pfadvariablen
####################
# Der Pfad zur Ampache Installation
# WICHTIG: Kein / hinter das Ende der Adresse setzen!
# Nehmen wir an, Ampache ist unter http://localhost
# erreichbar, dann muss hier nichts eingegeben werden.
# Falls Ampache jedoch z.B. unter http://localhost/music
# liegt, so wird an dieser stelle /music angegeben.
#web_path = ""
# Lang definiert die Sprache, die genutzt wird.
#lang = "fr_FR.UTF-8"
#########################
# Die libglue Variablen #
#########################
[libglue]
####################
# Unterhalb sind die Variablen für die Datenbank, mit der
# die Benutzer und auch die MP3-Informationen gespeichert werden.
# Hostname des Servers (Standard ist localhost)
local_host = localhost
# Name der Datenbank (Standard ist ampache)
local_db = ampache
# Benutzername für die Ampache-Datenbank
local_username = username
# Passwort für die Datenbank von Ampache (Darf nicht leer gelassen werden!)
local_pass = password
# Dauer einer Loginsession
local_length = 900
# Dies ist die Domain, fuer die das Cookie, in dem der Sessionkey gespeichert wird,
# ausgestellt wird. Diese Variable muss die Domain oder der Host des Systems sein.
# Andernfalls wird es unmoeglich sein, sich einzuloggen.
# Bitte ueberpruefe, ob zu Beginn ein . steht. (erforderlich!)
# Dies ist jedoch nicht notwendig, solange du die libglue fuer mehr als eine Seite
# nutzt.
# sess_domain = .yourwebsite.com
# Name der Session/des Cookie, dass zum Browser geschickt wird.
# Der vorgebene Wert sollte ausreichen.
sess_name = ampache
# Lebenszeit des Cookies. 0 == Immer (bzw. bis der Browser geschlossen wird),
# andernfalls wird hier die Lebenszeit in Sekunden erwartet
sess_cookielife = 0
# Ist das Cookie ein "sicheres" Cookie?
sess_cookiesecure = 0
# Pfad zur libglue (ist bei Ampache dabei)
# Kommentiere dies aus, wenn die libglue an einem anderen als dem Standardort liegt.
#libglue_path = "/data/ampache/libglue"
# Vordefinierte Fehlermeldungen.
# Diese sollten nicht editiert werden
empty_field = "Du hast eines oder mehrere Felder frei gelassen. Bitte gebe deinen Benutzernamen und das Passwort ein, um dich einzuloggen."
bad_auth_cred = "Anmeldung fehlgeschlagen. Dies liegt oft an einem Konfigurationsfehler seitens des Admins"
user_not_found = "Benutzername nicht gefunden."
login_failed = "Falscher Benutzername oder Passwort."
connect_error = "Konnte nicht zum Anmeldungsserver verbinden."
# Falls diese Datei existiert, kann sich niemand einloggen.
# Standard ist $prefix . /libglue/gone.fishing
# Kommentiere dies aus, falls die Datei anders heissen soll
#stop_auth = "/data/music/ampache/libglue/gone.fishing"
#################################
# Die Konfigurationsvariablen #
#################################
[conf]
####################
# Titel der Seite
site_title = "Ampache for the love of Music"
# Benutzer Zugriffsliste
# Schalte dies ein, falls Ampache auf die Zugrifssliste achten soll, und
# Streaming/Downloading/XML-RPC nur von bekannten Hosts erlauben soll.
# XML-RPC funktioniert nicht, ohne dass dieses angeschaltet ist.
#access_control = "true"
# Erzwinge Session
# Falls dies Variable auf true gesetzt ist, prueft Ampache, ob die URL
# eine gueltige Session ID besitzt. Dies hilft Einbrueche zu verhindern,
# die durch das Erraten von Session IDs auftreten koennen.
#require_session = "true"
# Benutze XML-RPC
# Erlaube XML-RPC Verbindungen. Falls du nicht willst, dass dein Katalog
# von einem anderen Ort aus gestreamt wird, kommentier dies aus.
#xml_rpc = "true"
# Sperren
# Sperre Lieder, wenn das gleiche Lied bereits gespielt wird.
#lock_songs = "true"
# Erzwinge HTTP-Abspielen
# Diese Einstellung ist standardmaeszig an, und erzwingt, dass m3u-URLS
# erstellt werden, selbst wenn du https nutzt. Diese Einstellung wurde
# vorgenommen, da es unseres Wissens keine https mp3-Streamingprogramme
# gibt ...
force_http_play = "true"
# HTTP Port
# Bitte setze diese Option, wenn du force_http_play nutzt, und wenn dein
# httpd auf einem anderen Port als 80 laeuft.
#http_port = "80"
# Falls diese Funktion auf false steht, wirst du spuerbare
# Performanceschuebe merken.
# Es ist empfehlenswert, dies auf false zu lassen, da die Funktion eh
# nicht genutzt wird ... :P
do_mp3_md5 = "false"
# Hier wird das Interval angegeben, in dem der aktuelle Fortschritt
# beim Katalogisieren ausgegeben wird. Bei grossen Katalogen sollte
# diese Zahl moeglichst gering gehalten werden.
catalog_echo_count = "100"
# Diese Option legt fest, welcher ID3 Tag bevorzugt wird.
# Diese Funktion wurde fuer diejenigen angelegt, die noch keine
# v2-Tags angelegt haben. Somit ist es bei manchen Nutzern hilfreich,
# v1 zu nutzen, bis die Kataloge auf v2 umgestellt sind.
id3tag_order = "id3v2"
id3tag_order = "id3v1"
# Kommentiere dies aus, wenn du nicht moechtest, dass Ampache
# symlinks folgt.
#no_symlinks = "true"
# Benutze Authentifizierung?
# Falls dies auf "Yes" gesetzt ist, sind zum Anmelden ein gueltiger
# Benutzername und ein gueltiges Passwort erforderlich.
# Falls dies auf Nein gesetzt ist, fragt Ampache nicht nach einem
# Benutzernamen und Passwort.
# "No" ist nur fuer Testsysteme empfehlenswert.
use_auth = "yes"
# Kuenstler- & Album Zwischenspeicherlimit
# Um die Katalog-Aktualisierungen zu beschleunigen, und um die Last
# auf MySQL zu reduzieren nutzen wir eine Art Zwischenspeicher, wo
# anhand einer ID MySQL-Abfragen gespeichert werden.
# Du kannst diese Option frei nach deinem belieben abaendern ...
album_cache_limit = "25"
artist_cache_limit = "50"
# Diese Option schaltet den Demomodus wahlweise an oder aus.
# Falls der Demomodus angeschaltet ist, kannst du keine Songs
# abspielen, oder den Katalog aktualisieren. In anderen Worten ..
# Lass es besser auskommentiert.
# demo_mode = "true"
# Amazon Developer Key
# Dies ist erforderlich, um die Amazon-Coversuche zu nutzen.
# Unter https://associates.amazon.com/exec/panama/associates/join/developer/application.html
# bekommst du einen solchen Key.
#amazon_developer_key = ""
# Hier wird das minimale Speicherlimit fuer PHP definiert. Falls
# PHP einen niedrigeren Wert in der php.ini hat, wird Apache den
# hier definierten Wert nutzen.
# Achtung: Den Wert auf keinen Fall unter 16MB setzen, sonst
# funktioniert getid3() nicht mehr!
# memory_limit = 16
# Aktualisierungs-Interval
# Falls dieser Wert gesetzt ist, wird Ampache die Hauptseite
# alle X Sekunden aktualisieren (neu laden).
# refresh_interval = 180
#######################################################
# Diese Optionen definieren, wie die Suche ablaeuft.
# Folgende Moeglichkeiten existieren: artist,album,song_title,song_genre,song_year,song_bitrate,song_min_bitrate,song_filename
search_field = song_title
# Suchtypen: fuzzy und exact
search_type = fuzzy
#########################################################
# Diese Optionen kontrolieren das "Downsampling" feature.
# Jedoch sind hierzu Tools wie lame erforderlich, mit
# denen man mp3s umwandeln kann.
# Wir empfehlen mp3splt und lame.
# %f = Dateiname
# %o = offset
# %s = sample rate
downsample_cmd = mp3splt -qnf "%f" %o EOF -o - | lame --mp3input -q 3 -b %s -S - -
# Temporaere Datei
downsample_tmp = /tmp/ampache.log
#######################################################
# These options control the "local play" feature. This requires
# a playlist manager such as moosic, winamp, xmms etc which
# can be controlled via command line.
# The defaults below are for moosic, a python based music
# player daemon. You must currently start the daemon
# yourself, because it doesn't fork right for launch
# inside apache.
# Valid replacements are:
# %URL% = url to the song
# Diese Optionen dienen der Konfiguration der "local play" Funktion.
# Dies erfordert ein Programm, dass mit Playlisten umgehen kann, und
# per Kommandozeile kontrolliert werden kann. Beispiele hierfuer
# sind moosic, winamp oder xmms.
# Die untenstehenden Standardwerte gelten fuer moosic, einen
# python-basierten music-player-daemon. Jedoch ist es erforderlich,
# den Daemon selber zu starten, da dies nicht automatisch passiert.
# Moegliche Veraenderungsmoeglichkeiten sind:
# %URL% = URL zum Lied
#
### ADD - Fuege einen Song zur Playlist hinzu
#localplay_add = "export HOME='/var/www'; moosic -n add %URL%"
### STOP - Beende das Abspielen des Songs
#localplay_stop = "export HOME='/var/www'; moosic stop"
### PLAY - Setze einen gestoppten Song fort, oder starte neu
#localplay_play = "export HOME='/var/www'; moosic play"
### PAUSE - Pausiere den Player
#localplay_pause = "export HOME='/var/www'; moosic pause"
### NEXT - Waehle den naechsten Song in der Liste
#localplay_next = "export HOME='/var/www'; moosic next"
### START - NICHT GENUTZT - starte den Player
#localplay_start = "export HOME='/var/www'; moosicd &"
### CLEAR - Alles von der Playlist loeschen und Abspielen starten
#localplay_clear = "export HOME='/var/www'; moosic wipe"
### KILL - Beende den Player
#localplay_kill = "export HOME='/var/www'; moosic die"
### Diese Zeile sollte einen 1 Zeilen langen "Status Report" umfassen,
### der unter den Player-Bedienelementen dargestellt wird.
#localplay_status = "export HOME='/var/www'; moosic state|grep 'items in the'"

3
config/motd.php.dist Normal file
View file

@ -0,0 +1,3 @@
<!-- This file contains any "Message Of The Day" Type information -->
<!-- It will be included below the log-in form on the login page. -->

771
docs/CHANGELOG Executable file
View file

@ -0,0 +1,771 @@
--------------------------------------------------------------------------
--------- Ampache -- CHANGELOG ---------
--------------------------------------------------------------------------
--------------------------------------------------------------------------
v.3.3.1:
- Fixed hardcoded HTTP reference in list_header.inc
(Thx hongyi_gao)
- Fixed refresh javascript for main page.
- Fixed <html lang=> tag so that it validates (Thx XGizzmo)
--------------------------------------------------------------------------
v.3.3.1-Beta2 05/22/2005:
- Included new Greyblock Theme (Thx Shieldb)
- Fixed playlists if use_auth == FALSE
- Tweaked CSS classing in an attempt to improve themeing. This
breaks all previous themes. (Thx mkeadle)
- Fixed problem with Color Boxes in IE (Thx rperkins)
- Tweaked the Main page adding most popular albums as well as
spliting out the mpd control and now playing.
(Thx Nedko and reflous)
- Fixed a problem with directories named '0' (Thx Protagonist)
- Fixed lack of seeding of RAND() which would cause Pre PHP 4.2
to not really have random playlists.
- Fixed a bug where guests could change their own password and
control MPD
- Fixed a ton of class formating inconsistencies as well as tweaked
a few tables. (Thx Rperkins)
- Fixed some consistency issues with where the A-Z listing was
between Albums and Artists, Added Bolding of currently
selected Letter/Number (Thx Rperkins)
- Fixed a problem with the admin preferences where the theme
colors wouldn't reset, if the target theme is the current
one of the user setting it (Thx Nedko)
- Fixed a problem with the CHARSET not being passed correctly
(Thx Nedko)
--------------------------------------------------------------------------
v.3.3.1-Beta1 05/01/2005:
- Added Random Play for Playlists
- Added Per User config option to set ellipse thresholds as well
as some index.php tweaks (Thx Nedko)
- Added support for SPX files.
- Fixed a problem that occurred when a userfield contained a single
quote (username,fullname etc)
- Turkish Translation, Charset iso-8859-9 added (Thx vireas)
- Flipped Actions on MPD Control, clicking on the title now skips
to the song, clicking on number removes it (Thx rastan)
- Tweaked Preferences look, adding color boxes showing the color
of the preference, and misc html/spelling fixes
(Thx Rperkins)
- Added Random On/Off to MPD controls and truncated songs with ...
(Thx Orion88)
- Added ability to pass a URL to MPD allowing it to be on a
different computer than the MP3's this also makes setup of
MPD a lot easier.
- Fixed Connected User Count.
- Fixed random HTML errors that caused custom themes to look wrong
--------------------------------------------------------------------------
v.3.3.1-Alpha2 04/23/2005:
- Added ability to import M3U's as playlists on catalog build and
from the playlist screen, note the m3u must exist on the
server. Uploading from client is not working
- Fixed a bug that caused it always to generate a m3u file when
using downsampling
- Added support for .mpc files
- Added .htaccess and renamed all /bin files to .php.inc so that
the webserver, even if it ignores the .htaccess won't try
to run the scripts
- Fixed ampache.cfg and /docs references in /install.php
(Thx rperkins)
- Fixed a typo that caused ASX playlists to not be populated with
the user_id as they should (Thx weidercs)
- Fixed a problem where when creating a new user it wouldn't take
the values from "Admin Preferences" as it should.
- Fixed catalog toolbox so it uses the classes rather than a
hardcoded color
- Fixed Installer which still had ../ references (Thx fakenick)
- Fixed a few more ../ references
- Fixed redirect to update.php on login after you've already
done the update. (Thx Orion88)
- Fixed login.php so that it loads the theme that is set in the
admin preferences correctly
--------------------------------------------------------------------------
v.3.3.1-Alpha1 04/21/2005:
- Added Themeing Ability to Ampache, see /themes/classic for an
example of how to do it
- Added Burgundy Theme (Thx s1amson)
- Moved everything into / instead of /docs you should now be able
to extract ampache directly into your webroot and have it
work perfectly :-)
- Added Config file compare to test.php
- Added config values to control allowed playback methods
- Added SlimServer class *Not Finished
- Tweaked catalog "Total Time" so it's a little more consistent
(Thx Andy Morgan)
- Fixed playback problem with Windows Media Player caused by a
misplaced Partial-Content header entry.
- Renamed ampache.cfg --> ampache.cfg.php and added <?php exit(); ?>
to prevent display of config file in web interface. this is
the first step towards moving away from the /docs style
(Thx s1amson)
--------------------------------------------------------------------------
v.3.3 04/17/2005:
- Fixed seeking and lack of http headers during normal playback
(Thx Nikk)
- Fixed random play bug where it wouldn't return any songs due
to a malformed sql statement. (Thx J)
- Fixed a typo that caused the song format to be ignored by play.php
(Thx Nikk)
- Fixed lack of an error message if amazon album art was a search
method, but no developer key was specified
- Fixed the memory allocation code.
- Fixed a lack of status reporting during the album art searches
now prints out Searched 100. . . like all other catalog
functions.
- Added User Registration (Thx Terry) *Not Finished!
- Fixed problem where an error would occur if only one album
art gathering method was selected.
- Fixed problem where it would continue to search for album art
when updating multiple songs from the same album where art
has already been found.
- Added Debug Script for Amazon Album Art search (in /bin)
- Cleaned up some dirty HTML, and redudant functions
- Fixed lack of redirect to the Install page if no config file is
found
- Fixed login page so it respects the values set in the database
for background color etc
- Fixed lack of cookie deletion on logout, and lack of session
removal...
- Added forced Garbage Collection at least 20% of the time.
- Fixed Installation Script, admin/changeme is no longer the
default username/password. Installation script creates
initial admin user
- Fixed html, and lack of web_path definitions on the account
page, also spruced up the look a little bit
- Switched all short tags to long tags (<? --> <?php)
- Fixed preferences so that it doesn't display an input field
if you don't have access to change said preference
- Fixed album art saying it's found when it really wasn't
- Fixed problem where changes to preferences weren't respected
if use_auth = false
- Fixed download, and direct link, both were not respecting
the song->type
- Tweaked m3u generation removing the \ before the filename to
prevent mp3blaster from failing (Thx Rubin)
- Added command line script /bin/compare_config looks at
ampache.cfg.dist and compares it to the ampache.cfg looking
for missing config values.
- Tweaked db update check so it does it on every page load, rather
than just on login.php (so use_auth=no gets checked)
- Fixed problem with user create and user edit where it wasn't doing
any really good error checking, or notifying you when it
failed to update/create
- Tweaked now playing in an attempt to allivate some now playing
floods that people were seeing
--------------------------------------------------------------------------
v.3.3-Beta4 03/27/2005:
- Added Batch Download functions (Thx RosenSama)
- Tweaked Main Page format (Thx Nedko Arnaudov)
- Added Full Album/Full Artist option to Random Play
- Fixed Amazon Album Art gathering, changed from SOAP
method to REST method, now works with PHP5 and PHP4!
- Fixed problem with ' being escaped one to many times in a
playlist name
- Tweaked MPD play so it uses the playlist_type and is accessed
by simply selecting the "Play" action
--------------------------------------------------------------------------
v.3.3-Beta3 03/17/2005:
- Fixed a problem with the preferences and display of the logout
button and inability to edit/disable songs/playlists when
use_auth = no
- Added volume controls to local play (Thx Vlad)
- Fixed a problem of importing comments from mp3 files (Thx Cucumber)
- Fixed a typo that caused the account you were logged in as to be
deleted rather then the account you wanted to delete.
- Added pulling missing song info from filename based upon the catalogs
file patterns.
- Improved error logging and handling.
- Added album art dump from database to file system (Thx Cucumber)
- Added show albums with no art on Albums browse page (Thx Cucumber)
- Fixed a problem where Localplay wouldn't return to index as it
should (Thx Jason)
- Added Installation Script (/install.php)
- Fixed lack of an sql_escape on comment which could break inserts
if comment contained " or '
- Added default log_path and better error message if unable to write
to the file
- Removed _SERVER['PHP_SELF'] reference on alphabet function due
to the fact it doesn't always get passed.
- Removed old setup.php in favor of new install.php
- Upgraded Moosic from 1.2.5 --> 1.5.1 which fixes some playback
issues (Thx soloport)
- Added Prev button to localplay and send the song name to the player
rather than simply song.mp3 (Thx jason)
- Added Customizable Stream Format, see config (Thx Cucumber)
- Added sort by Year on album page.
- Fixed some minor issues with the XMLRPC code.
- Fixed typo in style-sheet (Thx Nedko Arnaudov)
- Added cleaned up favicon (Thx Nedko Arnaudov)
- Added paging and sort by username/fullname & last_seen on
admin user page
- Fixed issue with non-us chr when truncating using ... on
global popular and album/artist views (Thx Nedko Arnaudov)
- Fixed importing of non-us chr from OGG files (Thx Nedko Arnaudov)
- Fixed an issue were duplicate headers would be sent during
downsampling, also remove extra db connection in play/index.php
- Fixed problem where now playing wouldn't show a username if use_auth
was disabled
- Fixed a problem which prevented you from updating a user
- Fixed an error in the logic that caused all art methods to be
searched regardless of config settings
- Added ASX playlists (Thx Samir Kuthiala)
- Added check for Iconv in /test.php
--------------------------------------------------------------------------
v.3.3-Beta2 02/09/2005:
- Added config option for site charset defaults to iso-8859-1
(Thx Nedko Arnaudov)
- Fixed unhandled soapclient errors with PHP5 - Note Amazon
album art search still doesn't work. It just doesn't
return an error.
- Fixed problem with winamp playback on .oggs
- Added "Remember Me" button that overrides local length setting
and sets a 1 year cookie
- Added new RSS page (Thx Speedy B)
- Changed how preferences are handled once again. In the process
fixed numerous bugs with preferences.
- Added Apply To All in admin preferences, letting a full admin
reset a specific pref for all users at once.
- Update Catalog no longer overwrites changes made in the interface
- Added MPD patch (Thx RosenSama)
- Suppress Error in /docs/play/index.php if fopen fails
- Fixed Random playback, it is now actually a random number of songs
in a random order from said artist/album
- Fixed Comment not getting set during song flag (Thx RosenSama)
- Added gimped support for m4a (ITunes) files, Genre and Track #
aren't imported due to getid3() limitations
- Fixed some XML-RPC issues that cropped up with newer versions
of PHP
- Improved fix for Mysql 4.1 PASSWORD function, should always
work now.
- Added basic logging functions (for debug)
- Fixed downsample so it actually looks at the ampache.cfg for the
command to run instead of being hardcoded in
- Added ability to set preferred filename for folder album art search
along with ability to set order of search methods (Thx Mike)
- Started tweaking MPD patch so that it can be accessed as a
play type
--------------------------------------------------------------------------
v.3.3-Beta1 12/26/2004:
- Fixed problem with download not detecting mime types and not seeing
true/false value of preference
- Added Patch from Shine with a _ton_ of gettext updates and an almost
complete German translation!
- Fixed automatic detection of server port (Thx Corsin)
- Fixed missing prefix on Albums by Artist page (Thx ianneub)
- Removed a large chunk of unneeded code from Main page
- Fixed some preferences problems which were allowing users to define
download/upload etc
- Fixed Upload functions created by Lamar to account for other changes
I've made to ampache, upload now shows up in menu bar
if you have upload enabled
- Added CLI catalog_update.php file in /bin that updates all local
catalogs
- Updated nusoap library to newest version (12/15/2004)
- Fixed upload, now requires a readable upload dir before even attempting
to upload, and correctly inserts/quarantines files
- Fixed a problem where the catalog clean wasn't removing files from
playlists when they were removed from the catalog
- Added 'pretty' count of songs checked during catalog clean
- Added simple m3u playlist format and fixed a small typo in the pls
playlists
- Added Direct Link that can be drug to winamp to "append" to
playlists (Thx jason)
- Fixed incorrect redirect on Disable/Enable of songs
- Fixed login problems due to change in HASH style with Mysql 4.1
- Fixed Albums with multiple artist giving incorrect song count and showing
single artist, rather than "Various"
--------------------------------------------------------------------------
v.3.3-Alpha3.1 11/29/2004:
- Fixed two typo's in /docs/playlist.php (Thx smichaelis)
- Added a or die to the table drop in /update.php to prevent silent
failure of update.
- Added check for session support on /test.php
--------------------------------------------------------------------------
v.3.3-Alpha3 11/28/2004:
- Fixed duplicate web_path entry in preferences (Thx KlaasVaag)
- Fixed some problems with the flagging single quotes and genre
should now work (Thx Cocobu)
- Added WMA support (Thx Ldary)
- Added new Getid3 version
- Fixed typo that prevented play selected on artist page from
working (Thx tPassive)
- Added WMA Album Art support... maybe
- Fixed problem with [Prev] & [Next] wrapping to a new line
- Added filename used for songs with no title
- Fixed ability to disable last account, or remove last admin account
- Added year to "Albums" view
- Fixed inability to delete playlists
- Fixed a problem introduced while cleaning up /lib/album.php
- Added new Stream class to make adding play types easier
- Added correct PLS file support. Set via a config option
- Added Favicon (Thx Rubin)
- Added German README/INSTALL/MIGRATION/ampache.cfg.dist (Thx phil)
- Added French Translation (Thx Cocobu)
- Removed defunct "findfile" script that was completely broken
- Added 1000 songs & All to random play (Thx clouser)
- Added Folder based search for any .jpg or .gif as album art only
works on catalog update & build (Thx dromio && roark)
- Added config options that define where ampache looks for art
- Fixed logic error on album art page, and redundant checks
- Fixed Non-Us CHR on ogg && id3v1 tags files importing incorrectly
- Fixed some web_path and prefix problems
- Fixed single quotes in folder names preventing the entire directory
from being indexed
- Added New Blank Album Image (Thx Aaron La'gere)
- Added Per Artist & Per Album Update From Tags
- Added GetText to albums.php, playlist.php, lib.php, index.php and
ui.php as well as new messages file. (Thx Shine)
- Added Album art shown on Now Playing (Thx Rubin/Shine) turned on by
setting play_album_art = "true" in ampache.cfg
- Fixed problem where flagged table wasn't getting cleared when you
deleted the song that it referenced
- Added "Guest" user level which can view, but not play or change
anything
- Added user_catalog table for future catalog access control, this
feature is not yet implemented.
- Added FLAC file support
--------------------------------------------------------------------------
v.3.3-Alpha2 11/08/2004:
- Improved error checking on Mysql connection it now redirects to
/test.php on failure rather than just throwing an error
- Added upload.php play/pupload.php & templates/show_upload.inc
for upload functionality (Thx Lamar!)
- Fixed a $dbh --> dbh() problem (Thx phil)
- Fixed the preferences requirement on update.php (Thx phil)
- Fixed "Fuzzy Counting" in the README file index.
- Fixed a typo in playlist that caused the header redirect
not to work
- Fixed setting of song->played value (Thx Mkeadle)
- Fixed Admin preferences for user 0 (what new users get)
- Added initial GetText, translation, support
- Added some of the initial French translation using to babblefish
- Fixed a problem with the album art clearing from the db correctly
- Added initial DE translation (Thx Phil)
- Fixed a problem with single-quotes in filenames breaking catalog
builds (Thx Naund)
- Added initial IceCast Support (Thx Thomas)
- Fixed incorrect naming of Local Play variable which caused it
not to work at all (Thx jpolansky)
- Added Valid Session Checking to play code that, if require_session
is set prevents anyone without a valid sid from playing music
- Added Album Year to Albums by Artist View and album table in db
--------------------------------------------------------------------------
v.3.3-Alpha1 10/04/2004:
- Fixed non-us chr showing up incorrectly
- Fixed session garbage collection
- Added check for function_exists iconv
- Added check for existence of mysql_query function to test.php
- Fixed a problem with verify single catalog (Thx Framercy)
- Reworked the Preferences, adding most of the non-critical
preferences from the config file and putting them into
the web interface
- Tweaked the DB to work with the new preferences
- Update.php now has a font size and bgcolor (defaults)
- Force short_tag = on in init.php
- Show Albums by Artist only checks DB for album art (faster)
- Added View Full Album Art (click on art on single album page)
- Removed dead code from /modules/lib.php
- Tweaked Personal Stats page. Moved out of lib.php into user
functions and cleaned them up a bit
- Removed extra , from Mail function and fixed From address
http://bugs.ampache.org/bug_update_page.php?bug_id=1
- Fast Update on Update Catalog function has some "Fuzzy" logic
- If Fast Update isn't checked, Update Catalog looks for album art
in the id3 tags
- Update Catalog now has "Checked 100...." messages like the
add to catalog function
- Added check for soapclient class already existing. (Thx Hopson)
- Tweaked Album Art on Albums by Artist Page (Thx clader)
- Added Play Random & Play All links to Albums By Artist Page
- Removed extra queries from Albumart.php
- Fixed Playlist Delete (Thx kellin)
- use_auth = "no" works as advertised
- Ability to import Album Art on catalog build from id3v2 tags
--------------------------------------------------------------------------
v.3.2 08/11/2004:
- Fixed XMLRPC duplicate function problems
- Fixed getid3() issues by manually setting memory limit for php
if current setting is below 16M
- Suppressed errors that occurred when PHP-GD tried to read a gif
image.
- Added auto refresh of index.php (Thx vireas)
- Fixed a problem where saying no to a user delete deleted it
anyway. (Thx Dogsbody)
- Fixed a problem with admins updating users preferences
- Removed Edit button from delete confirmation for playlists
- Improved /test.php a tiny bit
--------------------------------------------------------------------------
v.3.2-Beta2 07/12/2004:
- Yet more improvements to album art code, now checks for 1x1
images if you have GD installed (Thx mikej)
- Fixed a problem where \n or other whitespace would get into
album name
- Fixed catalog update destroying tags on ogg and rm files
- Added RSS feed page (thx speedyb) see /rss.php
- Fixed a problem with libglue that cropped up with 4.3.8
- Added install.pl (initial release)
- Fixed last seen again....
- Fixed up the test.php to it actually works correctly
- Added get album art from url Thx gwynnebaer
- Added config option to set default search type Thx gwynnebaer
- Tweaked headers to make them nicer with large numbers Thx gwynnebaer
- Tweaked preferences code so it works as advertised.
- Updated to GETID3() 1.7.1-b1 Woohooo!
--------------------------------------------------------------------------
v.3.2-Beta1 07/02/2004:
- Tweaked getid3 library in an attempt to prevent non-fatal
foreach error
- Replaced "no album art" image (thx Gargamale)
- Last Seen now actually works, can be viewed on the user
screen in the admin section
- Fixed a Artist catalog problem introduced with the new
getid3 library
- Now takes into account https vs http using _SERVER['https']
variable
- Added force_http_play which ignores https and always forms the
urls in the m3u as http, default is on
- Added http_port in case your http server isn't running on port 80
- Fixed a typo that caused clean_artist not to work with mysql 3.x
- Logical Random play query (Thx Famercry and mikepell)
- Updated the XMLRPC library and hopefully improved it a little :)
- Improved Ampache.pm no longer requires secrets file and automatically
find path information (ignore errors :P)
- Added rename_all & sort_all to fileupdate.pl in /bin
- Fixed a problem where play_type == 'local_play' wouldn't actually
do anything
- Added sweet new album art code from MikeJ that searches Amazon
(Requires Developer Key, see config file)
- Applied some fixes to the album art (Thx gwynnebaer!)
- Added MOTD on the login page (see README)
- Fixed another seek problem (Thx gwynnebaer)
--------------------------------------------------------------------------
v.3.2-Alpha3 06/13/2004:
- Added last_seen to user table now tracks when they last
visited ampache
- Changed the preferences table to key,value pairs makes it
easier to add new preferences without having to update
the database again
- Put in initial down-sampling work
- Updated Ampache.pm and fileupdate.pl (Thanks Matt Shaffer and Nikk)
- Fixed a problem with the play count when you tried to seek
a file.
- Made the single album view a little nicer looking
- Added "Reset Album Art" action that removes the album art from the
database and re-querys the mp3s
- You can now select multiple genres when using Play Random
- Changed default action for albums/artists to browse per Alphi's
recommendation.
- Fixed a bug introduced into the config file.
- Finally fixed web_path so that you only need to define the path
to ampache (ie /music) rather than the full URL such as
http://localhost/music.
- Added another fix so that it takes into account the port when
logging in (was ignoring it before) Thx DogsBody
- Fixed a playback problem where song would reset after the
php max execution time Thx Nicolas Savoret
- Fix for some web_path vs web_host problems Thx Nick Wilson
- Fixed it so that disabling a user actually works now
- Playback now pays attention to disabled status and make sure
uid ends up being a valid user
- Reworked preferences, adding play_type in place of multi-cast
down-sample and local_play
- Down-sampling should now work if play_type is set to down-sample
and you do a little manual configuration
- Tweaked filename passed to players so that oggs work a little
better - Thx Dale Cooper and Gwynnebaer.
- Upgrade to newest GetID3 library - Thx Gwynnebaer!
- Initial support for RM files (Not Tested)
--------------------------------------------------------------------------
v.3.2-Alpha2.1 04/27/2004:
- Fixed a problem with the user functions which was handling
passwords in a _very_ bad way.
- Updated the title tag on now_playing
--------------------------------------------------------------------------
v.3.2-Alpha2 04/24/2004:
- Put Prefix back in Artist name
- Fixed Text echoed out during a catalog update, and made the
catalog update actually work!
- Fixed Prefix problems on album view and simplified the code
for displaying albums.
- Albums by Artist page now shows all of the Album art. (Thx MrBlahh)
- New Blank Album Image
- Weighted Random Play (Thx Mikepell)
- Fixed a the removal of disabled songs.
- Cleaned up and fixed basic user functions
- Reorganized the Main Page moving recently added albums/artists
on to the front page.
- Fixed Catalog Functions so that it removes old stats when
you clean/update/delete.
- Updated Database getting ready for XML-RPC
- Reintroduced Access Lists allowing for XML-RPC permissions
and stream/download permissions
- Added XML-RPC code back in (Experimental & DANGEROUS!!)
must be turned on in ampache.cfg
- Moved Config File to $ampache/config from $ampache/modules
makes more sense there....
- First step towards quick time playback capabilities (Thx Nick)
- Fixed a problem with catalog genre names that put an extra
slash in genres with " or '.
- Added Clear Now Playing under catalog tools in case you get some
funky data stuck in the now playing queue.
- Fixed user deletion. Preferences and stats were being left behind
- Hopefully fixed Album/Artist/Song Cleaning so that it works with
Mysql 3.23 (We were using 4.0+ sql syntax)
- Updated Now Playing to show album link and shortened song title
if needed
- User functions should always return to the user page when done.
--------------------------------------------------------------------------
v.3.2-Alpha1 03/23/2004:
- Added Now Playing
- Updated the migration tool (update.php)
- Added ability to turn on/off ability to download songs
- First step towards upload capabilities
- Early version of "Local Play"
- Per User preferences
- "Legalize" option that only allows one copy of a song to be played
at any one time.
- Fixes for popular songs being incorrectly reported.
- Fixes to Play All Songs by Artist/Album
- Improvements to playlists.
- Many other minor bug fixes
--------------------------------------------------------------------------
v.3.1.3 01/11/2004:
- Fixed a link problem on the logout page
- Fixed Full Album not being displayed in the title tag on show_songs
- Doesn't try to show album art for Unknown Albums
- Fixed a config problem introduced in 3.1.2
- Stops looking for album art after finding a single one (reduces load)
--------------------------------------------------------------------------
v.3.1.2 12/30/2003:
- Fixed Single Song Per Album bug if the album title contained
a single-quote
- Fixed problems with quotes, and special chr in id3 tags
- Fixed a few html problems
- New version of Getid3() see www.getid3.org
- Fixed Connected user count looking incorrect
- Cleaned up HTML in show_songs.
- Now returns an error if adding a user fails
- Fixed Stat Clean and Catalog Delete still happening even if you
clicked no
- Removed Clean All Catalogs and Access link because those
features are currently broken
--------------------------------------------------------------------------
v.3.1.1 12/26/2003:
- Fixed a problem with the clean catalog function not actually
working correctly, also added a check-box to auto delete
dead songs
- Fixed a problem with readconfig not working on windows
- Fixed a problem where dead songs would get added to a playlist
- Added a missing break in the case function of admin/catalog.php
- Removed preferences tab because it doesn't actually work
- Made Catalog Update not display errors if it can't find the file
- Catalog Update should no longer time out
- Added in some escaping for single quotes in some extra id3
fields
--------------------------------------------------------------------------
v.3.1, 12/23/2003:
- Fixed problem with quick search on artist only allowing 1 chr
- Fixed broken image on albums with no art
- General HTML cleanup
- Changed link name to "Play" from m3u
- Ordered genre pull down by name rather than ID
- Make it not look for album art if it wasn't viewing an album
- Removed random play stuff from album page
--------------------------------------------------------------------------
v.3.1-Beta2, 12/16/2003:
- Fixed double http:// in a few places (Thx Lamar)
- Typo in Form variable (Thx Lamar)
- Album Playlist Fixes (Thx Lamar)
- Added trailing slash to admin links (Thx MrBlahh)
- Removed from register globals requirements
--------------------------------------------------------------------------
v.3.1-Beta1, 12/10/2003:
- Completed support for OGG files (Thx Hopson for original code)
- Fixed Viewing Albums
- Addtype no longer required in apache config. Headers
are now passed in that delicate grey zone where all the
browsers we can find seem to work.. (Thx Rubin)
- Fixed it so that you no longer have to edit init.php (Thx Rubin)
- Added view all songs from this artist
- Hopefully fixed libglue once and for all...
--------------------------------------------------------------------------
v.3.1-Alpha5, 11/29/2003:
- Added Duplicate song checker to catalog tools (Thx Alphi)
- Fixed missing Genre check when updating id3 tags
- Added Disable Option for Admins when showing songs
- Removed some un-needed files
- Fixed 'Fuzzy' Math in list_header (Thx Andy)
- Fixed stats on the main page (Thx Andy)
- General Code Cleanup (Thx Andy)
- Fixed double login problem
--------------------------------------------------------------------------
v.3.1-Alpha4, 11/27/2003:
- Yet more search options
- Fixed a few more admin tool issues
- Added a play via Genre + Catalog (Thx Rubin)
- Fixed Random Play (Rubin)
- Fixed catalog so that if file exists but isn't readable
it doesn't add it to the catalog empty (Thx Andy Morgan)
- Fixed update.php to check what version of the db is being run
and update accordingly (Rubin)
- Added bare bones for Album Art support from the mp3 files (Rubin)
- Fixed Play Selected from Albums/Artists
--------------------------------------------------------------------------
v.3.1-Alpha3, 11/25/2003:
- Fixed some installation problems
- Added a few new search options
- Fixed catalog delete, and other misc link problems
- Added migration tools (Thx Andy Morgan)
- Re-worked Genre
--------------------------------------------------------------------------
v.3.1-Alpha2, 11/24/2003:
- Start of complete re-write of ampache code
- Fixed register globals problem, should no longer be required to be on
- Added ID3V2 tag support
- Improved playlists, added track var
- New Looks and feel thanks to Ben Shields
- Completely rebuilt cataloging again...
- Fixed orphaned files
==========================================================================
v.3.0, 04/05/2002:
- Added Randall Ehren to the "Ampache Development Team" :-)
- Completely rebuilt catalog mechanism
- Remote catalog updates via XML-RPC
- Fixed orphaned file interface
- New tools to update ID3 tags easier
- Changed admin interface to be easier to use
- Many bug fixes
--------------------------------------------------------------------------
v.2.5, 03/04/2002:
- Bug fixes and code cleanup
- Final mod_mp3 only version
v.2.0, 02/05/2002:
- Added stats page to clean up "Home"
- Made default album/artist view start with match=A
- Cleaned up admin/users interface to show who's logged on
- Added ability to anonymously mail all users via admin
--------------------------------------------------------------------------
v.2.0rc2, 01/18/2002:
- Fixed update catalog tools to remove songs that have changed
- Added support for the mod_mp3 MySQL dispatch -> you no longer need
to restart apache for new songs
- Minor interface fixes (spelling, wording, etc)
- Added per-user statistics
- Made album/artist views easier to digest
--------------------------------------------------------------------------
v.1.21, 07/29/2001:
- Minor bug fixes from various users (see readme)
- Updated Album and Artist views
- Added play all songs from artist and randomize songs from artist
--------------------------------------------------------------------------
v.2.0rc1, 01/10/2002:
- User/session management for admin
- fix 'Greatest Hits' problem
- Wrote setup.php for initial setup of server
- Reworked administration pages
- Per user profile settings/updates
- Playlists stored per user
- Private/Public playlists
- Show most popular songs/artist
- Added play.php wrapper to track song play
- Added stats for number of times played for artist/album/song
- Add demo mode
- Tweak album view to show artist as well
- Change format/view of "Home" page
- show songs for an artist on album page
- fixed single song play
- select all feature for song view
- greatly enhanced search result capabilities
- Show how many users connected
---------------------------------------------------------------------------
v.1.20, 07/22/2001:
- Lots and Lots of bug fixes
- Replaced mp3.php class with Sandy McArthur, Jr's id3 class
- Song editor -> update DB and/or song file -> integrate with orphan files
- Add genre support and allow genre playback and stats
- Add track support ... now should order in album order
automatically if ID3v1.1 tags used
- ID3v1.1 support for writing/reading files
- Tweak filefind to make filename be name of orphaned songs
- Moved "Orphaned Files" into the admin section
--------------------------------------------------------------------------
v.1.10, 05/08/2001:
- PHP-only version now; can catalog all MP3's via PHP
- Tweaked perl script to not return SQL errors
- More interface tweaks to make site look purdy
--------------------------------------------------------------------------
v.1.07, 05/04/2001:
- Changed URL for mod_mp3 to media.tangent.org
- Tweaked interface even more and cleaned up build process even more.
--------------------------------------------------------------------------
v.1.06, 05/04/2001:
- Many more updates to the tools and interface.
--------------------------------------------------------------------------
v.1.04, 04/29/2001:
- Prettied up interface some more.
- Tweaked code for .pls support (added artist, album)
- Fixed filefind to work around .AppleDouble directories
--------------------------------------------------------------------------
v.1.03, 04/29/2001:
- All kinds of build changes.
- Added support for .pls
--------------------------------------------------------------------------
v.1.02, 04/29/2001:
- Minor build changes.
--------------------------------------------------------------------------
v.1.01, 04/29/2001:
- First version.
--------------------------------------------------------------------------

280
docs/GPL-LICENSE Executable file
View file

@ -0,0 +1,280 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
^L
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

189
docs/INSTALL Executable file
View file

@ -0,0 +1,189 @@
-------------------------------------------------------------------------------
------------------ INSTALL - Ampache v.3.3 - 03/27/2005 -----------------------
-------------------------------------------------------------------------------
I'm assuming that you have Apache, PHP and MySQL running when you
get to this point.
If you're upgrading from 3.0 to 3.1 please refer to the MIGRATION Notes.
Your database can't be re-used, but fear not the Ampache guys thoughtfully
included scripts to port the data from your old database to the new one.
(They get an extra beer for that one)
If you're upgrading from 3.1 to a newer version refer to the MIGRATION Notes.
There should be an automated update script which will allow you to keep your
current database.
If at any time during this install you can't figure out where you have gone
wrong check out /test.php for help.
1. Installing Using the Web Interface:
As of 3.3-Beta3 Ampache includes an web based installation script. In order
for the script to work correctly you will need a user that has Database
create and modify rights for your mysql server. To use this script simply
visit /install.php. If you get a Access Denied make sure that your /config
directory does not contain an existing ampache.cfg
Web Install:
Step 1 - Inserting the database, this requires you to enter
a username/pass for MySQL that is able to create
a brand new database and insert new tables. This does
not have to be the user you actually run ampache as
Step 2 - Creating the Config file, this step asks for a 'user'
level account for MySQL that has full access over
the newly created ampache database, this can be the
same as the last step, but it is not recommended.
Ampache will attempt to write the config file directly
to the /config directory, if it isn't able to it
should prompt you to download the ampache.cfg simply
put it into /config and then visit the login page.
Step 3 - Creating the Initial User Account, you will be asked
for a username and password for the administrator
account.
Enjoy! If you have any problems with the web installer please report them
to vollmerk@ampache.org Thanks!
2. The Long of Setting Up Ampache
2.1 Configuring Apache Server
There are really two choices here. You can either configure a virtual
server for the ampache services, or you can just configure a new directory
directive for ampache. There are advantages and disadvantages for both.
If you configure a new virtual server, it has it's own log files which
could be useful for separating the ampache web traffic from the regular
web server traffic.
If you configure a new directory directive for ampache, the ampache
statistics will be in with all the other web traffic, but it may be a
little easier (but not by much).
We've included cronolog lines. These are not required, but for
troubleshooting we recommend them.
for a separate virtual server httpd.conf reads:
[snip]
<VirtualHost 192.168.100.2:80>
ServerName tunes.ampache.org
ServerAdmin webmaster@ampache.org
DocumentRoot /data/www/ampache
DirectoryIndex index.php
</VirtualHost>
[snip]
Now perform an 'apache restart' and apache should be configured.
2.2 Configuring Your MySQL Server
Setup a user and pass for your music db and create the music db.
Run: 'mysql -u user -p musicdb < sql/ampache.sql'
to create the music db and tables.
2.3 Configuring Ampache
2.3.1 Configuring motd.php
Copy config/motd.php.dist to config/motd.php
Edit this file however you like, with either php code or straight html.
The output will be displayed below the login box on login.php.
3. Running Ampache For The First Time
Point your browser at your new ampache webpage and you should get
the installation page. It will run you through inserting your
database, creating your config file and setting up your first user
Grab A Beer....
3.1 Setting up a catalog
First, create your local catalogs. Do this my first clicking
`Add a catalog', and entering the path for the root of your
collection of MP3 files. There is no need to enter sub directories
since the update tool will recursively catalog all subdirectories.
You can enter multiple paths, so this means that you can access
multiple directories, and hence multiple hard disks. I solved this
particular problem by patching the kernel to include logical volume
management, but that's a completely different story.
3.2 Updating your Catalog
If everything went correctly, you are now looking at an empty ampache.
In order to populate the database with all the tag information from
your MP3 files, you'll need to go to the `Admin' page, and select
the `Catalog' link.
Finally, you want to click the `Update All Catalogs' button in the
middle of the Catalog page and go for coffee (or any other beverages
you like) as this will take a little bit of time. The web server
is now searching for and opening each of the MP3 files in your
collection, pulling the ID3 tag data out, and using these to populate
your ampache database.
Final Note on MP3 Tags:
Since you the value of ampache is directly related to the data in the
database, and this data is obtained from the ID3 tags in your MP3 files,
it really pays to have all your tags populated and in order.
One of the best tools that I've run across to do this is:
EasyTAG - Tag editor for MP3 and OGG files
http://easytag.sourceforge.net
It runs right on the Linux machine, and is quite a bit faster at updating
tags than any PC based programs that have to access the MP3 across a
Samba share point. But this does not mean that you can't update tags
this way. Just that the local Linux program can access the MP3 faster.
If you insist on using a windows version another good tool can also be
found on sourceforge at: http://massid3lib.sourceforge.net/
3.3 Adding Users
To Add Users simply click admin->users->Add a new user and enter
the appropriate information
3.4 Sorting and updating files (Under Development)
When updating catalog preferences new fields added in v3.1 include
ID3 set command
Filename pattern
Sort Pattern
When these fields are populated a periodic update may be performed by scheduling
the fileupdate.pl program to run at timed intervals. This program will query the
database and attempt any requested updates. Before fileupdate.pl can be run, the
Ampache.pm file must be edited to reflect your archive information.
Usage of fileupdate.pl is as follows:
fileupdate [--id3|--rename|--sort|--all] [--help] [--pretend] [--verbose]
--pretend Display command taken, without actually doing anything.
--id3 Update id3 tags for all files flagged with 'id3'
--rename Rename files flagged with 'rename'
--sort Sort files flagged with 'sort'
--all Performs id3 update, rename, and sort
for all files flagged with 'id3'
--verbose Shows detailed information about what's happening.
--help This message
An example usage would be to schedule a cron tab which will run fileupdate.pl with
the appropriate arguments which runs every 6 hours.
EXAMPLE:
If you were to place the following line in your crontab:
* 24 * * * /apache/bin/fileupdate.pl -all
any updates applied to the database would be applied at midnight everyday

252
docs/INSTALL.de Normal file
View file

@ -0,0 +1,252 @@
-------------------------------------------------------------------------------
------------------ INSTALL - Ampache v.3.2 - 08/11/2004 -----------------------
-------------------------------------------------------------------------------
Ich gehe davon aus, dass Apache, PHP und MySQL bereits laufen, wenn du hier
angelangt bist.
Falls du von 3.0 auf 3.1 upgradest, schau dir bitte die MIGRATION Hinweise
an. Die Datenbank kann nicht weitergenutzt werden, aber glücklicherweise
haben wir einige Scripts entwickelt, um die Datenbank in das neue Format
zu konvertieren. (Dafür gibts ein extra Bier :P)
Falls während der Installation irgendetwas schieflaufen sollte, schau dir
zunächst die /test.php an, um an Hilfe zu gelangen.
1. Schnellinstallation:
mysql -u <Benutzername> -p <Datenbankname> < $root/ampache/sql/ampache.sql
Editiere die /etc/apache/httpd.conf
Lass das Webroot auf $root/ampache/docs zeigen.
[snip]
Alias /ampache/ /usr/share/ampache/docs/
<Directory /usr/share/ampache/docs>
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
[snip]
Starte danach Apache neu.
Verschiebe $root/ampache/config/ampache.cfg.dist nach
$root/ampache/config/ampache.cfg
Editiere $root/ampache/config/ampache.cfg
Besuche $web_adresse/login.php und melde dich mit den folgenden Daten an:
Benutzername: admin
Passwort: changeme
2. Der längere Weg
2.1 Apache konfigurieren
An dieser Stelle gibt es zwei Möglichkeiten. Etnweder kannst du einen
Virtual Server für Ampache konfigurieren, oder du kannst Amapche einfach
in ein freies Verzeichnis installieren. Beide Wege besitzen Vor- und
Nachteile.
Wenn du einen Virtual Server einrichtest, besitzt er seine eigenen
Logfiles, die hilfreich beim Berechnen des Traffics sein könnten
(Unterscheidung von Ampache- und normalem Traffic).
Wenn du ein neues Verzeichnis für Ampache nutzt, wird der Traffic von
Ampache zusammen mit dem der anderen Anwendungen brechnet. Der Vorteil
hier ist, dass die Installation u.U. einfacher ist.
We've included cronolog lines. These are not required, but for
troubleshooting we recommend them.
Der Eintrag für einen eigenen Virtual Server lautet folgendermaßen:
[snip]
<VirtualHost 192.168.100.2:80>
ServerName tunes.ampache.org
ServerAdmin webmaster@ampache.org
DocumentRoot /data/www/ampache/docs
DirectoryIndex index.php
</VirtualHost>
[snip]
Nac einem Neustart sollte Ampache nun richtig konfiguriert sein.
2.2 MySQL konfigurieren
Wir legen an dieser Stelle einen eigenen User für Ampache an.
Dazu ist folgender Befehl erforderlich:
'mysql -u user -p pass < sql/ampache.sql'
2.3 Konfiguration von Ampache
2.3.1 Konfiguration der ampache.cfg
Kopiere zuächst die config/ampache.cfg.dist nach
config/ampache.cfg.
Öffne dann die config/ampache.cfg.dist und editiere die
Vairablen:
# Hostname des Datenbankservers
local_host = localhost
# Datenbankname
local_db = ampache
# Datenbank-Benutzername
local_username = <mysql_login_name>
# Datenbank-Passwort
local_pass = <password>
# Logindauer in Sekunden
local_length = 900
# Dies ist die Domain, fuer die das Cookie, in dem der Sessionkey gespeichert wird,
# ausgestellt wird. Diese Variable muss die Domain oder der Host des Systems sein.
# Andernfalls wird es unmoeglich sein, sich einzuloggen.
# Bitte ueberpruefe, ob zu Beginn ein . steht. (erforderlich!)
# Dies ist jedoch nicht notwendig, solange du die libglue fuer mehr als eine Seite
# nutzt.
# sess_domain = .yourwebsite.com
# Name der Session/des Cookie, dass zum Browser geschickt wird.
sess_name = ampache
# Lebenszeit des Cookies. 0 == Immer (bzw. bis der Browser geschlossen wird),
# andernfalls wird hier die Lebenszeit in Sekunden erwartet
sess_cookielife = 0
# Ist das Cookie ein "sicheres" Cookie?
sess_cookiesecure = 0
prefix = "/<ampache_root>"
# This should not include http:// or any part of the host name
# ampache detects hostname and port automaticly
# Hier sollte kein http:// oder irgendein Teil des Hostnames
# stehen. Hostname und Port werden automatisch erkannt.
web_path = "/<path to ampache>"
site_title = "Ampache!!!"
# Sollte ausgeschaltet bleiben, ansonsten wird die Performance sehr drunter leiden.
do_mp3_md5 = "FALSE"
# Hier wird das Interval angegeben, in dem der aktuelle Fortschritt
# beim Katalogisieren ausgegeben wird. Bei grossen Katalogen sollte
# diese Zahl moeglichst gering gehalten werden.
catalog_echo_count = "25"
# Diese Option legt fest, welcher ID3 Tag bevorzugt wird.
# Diese Funktion wurde fuer diejenigen angelegt, die noch keine
# v2-Tags angelegt haben. Somit ist es bei manchen Nutzern hilfreich,
# v1 zu nutzen, bis die Kataloge auf v2 umgestellt sind.
id3tag_order = "id3v2"
id3tag_order = "id31v"
# Kommentiere dies aus, wenn du nicht moechtest, dass Ampache
# symlinks folgt.
#no_symlinks = "true"
# Benutze Login-/Authentifizierungssystem?
use_auth = "yes"
# Kuenstler- & Album Zwischenspeicherlimit
# Um die Katalog-Aktualisierungen zu beschleunigen, und um die Last
# auf MySQL zu reduzieren nutzen wir eine Art Zwischenspeicher, wo
# anhand einer ID MySQL-Abfragen gespeichert werden.
# Du kannst diese Option frei nach deinem belieben abaendern ...
album_cache_limit = "25"
artist_cache_limit = "50"
2.3.2 Configuring motd.php
Copy config/motd.php.dist to config/motd.php
Edit this file however you like, with either php code or straight html.
The output will be displayed below the login box on login.php.
3. Der erste Start von Ampache
Besuche mit deinem Browser die frisch installierte Ampache-Seite,
und es sollte das Anmeldeformular erscheinen.
Das Passwort und der Benutzername für den ersten Login lauten:
Benutzer: admin
Passwort: changeme
Jetzt kannst du dir ein Bier holen .. ;)
3.1 Einen Katalog einrichten
Zunächst gilt es, einen Katalog einzurichten. Dies geschieht, indem
man auf "Katalog hinzufügen" klickt, und dort den Pfad zur
MP3-Sammlung angibt. Es ist nicht notwendig, alle Unterverzeichnise
einzeln anzugeben, da die angegebenen Verzeichnise rekursiv
durchsucht werden.
3.2 Aktualisieren der Kataloge
Falls alles einwandfrei gelaufen, hast du nun einen leeren Ampache
vor dir. Um diesen Zustand zu veraendern, gehe unter der
Administrationsseite auf den Katalog-Link.
Nun fehlt nur noch ein Klick auf "Alle Kataloge aktualisieren", und
die Datenbank wird gefuehlt. Dies kann eine Weile dauern, da der
Webserver nun jede einzelne Datei auf ihren ID3-Tag hin untersucht,
und diese Daten in die Datenbank einspeist.
Final Note on MP3 Tags:
Abschliessende Bemerkung zu den ID3-Tags:
Da Ampache seine Daten aus den ID3-Tags bezieht, ist es wirklich
empfehlenswert, diese sauber und geordnet zu halten.
Eines der besten Tools für diesen Zweck ist EasyTAG, ein Tageditor
für MP3- und OGG-Dateien:
http://easytag.sourceforge.net
Es läuft direkt auf dem Linuxrechner, und ist somit ein wenig schneller,
als wenn man die ID3-Tags erst ueber Samba oder NFS aktualisiert. Das
heisst natuerlich nicht, dass dies geht .. Es geht lediglich darum, dass
dieses Programm schneller auf die ID3-Tags zugreifen kann.
Falls du darauf bestehen solltest, Windows zu nutzen, findet sich unter
http://massid3lib.sourceforge.net/ eine weitere gute Software, für den
selben Zweck.
3.3 Benutzer hinzufügen
Um Benutzer hinzufügen, genügt es unter Administration -> Benutzer
-> Benutzer hinzufügen zu gehen, und das dortige Formular mit den
entsprechenden Informationen zu versehen.
3.4 Sortieren und Aktualisieren der Dateien (Wird noch entwickelt)
In Verbindung mit dem Update der Katalogeinstellungen, sind in v3.1
folgende Felder hinzugekommen:
ID3-Kommando
Dateinamenmuster
Sortiermuster
Nachdem diese Felder mit Werten versehen wurden, steht einem regelmäßigem
Update mithilfe von fileupdate.pl nichts mehr im Wege.
Dieses Programm fragt die Datenbank ab, und nimmt die neusten Aktualisierungen
vor. Bevor fileupdate.pl ausgeführt werden kann, muss die Ampache.pm editiert
werden, sodass sie die notwendigen Archivinformatioenen enthält.
Benutzung von fileupdate.pl:
fileupdate [--id3|--rename|--sort|--all] [--help] [--pretend] [--verbose]
--pretend Stelle das angegebene Kommando dar, ohne etwas zu machen.
--id3 Aktualisiere ID3-Tags von allen mit 'id3' markierten Dateien
--rename Benenne alle mit 'rename' markierten Dateien
--sort Sortiere alle mit 'sort' markierten Dateien
--all Nehme ID3-Update vor, bennene und sortiere alle Dateien um,
die mit 'id3' markiert wurden.
--verbose Zeige detailierte Informationen
--help Diese Nachricht
Beispiel:
Folgender Eintrag nimmt regelmäßige um Mitternacht alle erforderlichen Updates
vor:
* 24 * * * /apache/bin/fileupdate.pl -all

39
docs/MIGRATION Executable file
View file

@ -0,0 +1,39 @@
-------------------------------------------------------------------------------
--------- MIGRATION - Ampache v.3.3 -----------
-------------------------------------------------------------------------------
- Migrating from Ampache 3.3 --> 3.3.X+
Rename your /config/ampache.cfg to /config/ampache.cfg.php
- Migrating from Ampache-3.1.0 --> 3.3
Follow the instructions found in $yourwebsite/update.php
- Migrating from Ampache-3.1-Alpha2 or Alpha --> Ampache 3.1-Alpha3
Please visit $yourwebsite/update.php to update the genre table.
If you are updating from Alpha2 to Alpha3 or higher.
This will invalidate your current catalog.
- Migrating from Ampache-3.0 --> Ampache3.1
There are currently a few tools to help migrate your Users and your
playlists from Ampache 3.0 to Ampache 3.1.
* Note these tools will _NOT_ work against 3.2 or 3.3 they are no
longer maintained.
1. Install and setup Ampache3.1 in a new Database.
2. Edit the approiate parameters in the following files
/bin/migrate_user.pl
/bin/export_playlist.pl
/bin/import_playlist.pl
3. Run the desired script.
These perl scripts were created by Andy Morgan

31
docs/MIGRATION.de Normal file
View file

@ -0,0 +1,31 @@
$CVSHeader: ampache/MIGRATION,v 1.2 2004/03/23 08:33:18 vollmerk Exp $
MIGRATION - Ampache v.3.1 - 11/26/2003
- Umwandlung von Ampache-3.1.X --> Ampache 3.3
Folge den Anweisungen unter $ampache/update.php
- Umwandlung von Ampache-3.1-Alpha2 oder Alpha --> Ampache 3.1-Alpha3
Bitte besuche $ampache/update.php um die Genre-Tabelle zu
aktualisieren.
Falls du von Alpha2 auf Alpha3 aktualisierst, wird dein
Katalog jedoch ungültig, und muss neu angelegt werden.
- Umwandeln von Ampache-3.0 --> Ampache3.1
Es gibt momentan einige Tools, um die Benutzer und Playlisten
von Ampache 3.0 auf Ampache 3.1 upzudaten.
1. Installiere und konfiguriere Ampache3.1 in einer neuen
Datenbank.
2. Editiere die entsprechenden Parameter in diesen Dateien:
/bin/migrate_user.pl
/bin/export_playlist.pl
/bin/import_playlist.pl
3. Führe das entsprechende Script aus.
Die Perlskripte wurden von Andy Morgan erstellt.

149
docs/README Executable file
View file

@ -0,0 +1,149 @@
-------------------------------------------------------------------------------
--------- README - Ampache v.3.3 -----------
-------------------------------------------------------------------------------
Contents:
1. Intro
a) Supported File-Types
b) Supported Stream Methods
c) Current Translations
d) Thanx
2. Getting all the components
3. Setting Up
a) Upgrading
4. License
a) Donations (Beer!)
5. Contact info
1. Intro:
Ampache is a PHP-based interface to a MySQL database
where information about your audio files are stored. The songs
are streamed using PHP; older versions required mod_mp3 but this
version no longer does. The songs are cataloged via PHP
scripts.
These tools are heavily dependent on quality tags in your audio
files and or the file system organization. If you've kept them
up-to-date or organized this is the tool for you.
See CHANGELOG for version information.
A) Supported File-Types
Ampache currently supports the following audio file types. If
you would like ampache to support an additional file type please
contact us on irc, or the forums and we will investigate adding
them. Thanks
- MP3 (id3v1 && id3v2)
- OGG
- WMA
- FLAC
- RM
- AAC/M4A
- MPC
B) Supported Stream Methods
Ampache currently supports the following different methods for
streaming your audio files. Please contact us if you would like
to see additional methods.
- Single Stream
- extended m3u
- simple m3u
- standard pls
- ASX
- Realtime Downsampled
- Localplay using Moosic
- Localplay using MPD
- Icecast2 Stream
C) Current Translations
Ampache is currently translated into the following languages. If
you are interested in updating an existing translation or adding
a new one please contact us at translation@ampache.org or see
/locale/base/TRANSLATIONS for more instructions.
- English (en_US)
- German (de_DE)
- French (fr_FR) *Partial
D) A Special Thanks:
Thanx to those who've helped us make Ampache so useable:
Scott Kveton - Head Nacho, inventer of all that is Ampache
Robert Hopson - Libglue, Playlists, Ogg support.. and much more
Andy Morgan - Protagonist
RosenSama - Developer
Randall Ehren (Initial XML-RPC)
s1amson (lots of beta testing)
Caleb Crome (bug fixes and enhancements)
Mike Payson
Jon Disnard
Adriaan Peters (numerous patches and bug fixes)
Rob Kaandorp (time calculation fix)
Ian Cote (MP3.php tweaks)
Kurt Lieber (random fixes)
Maan Bsat (random fixes)
latka (from media.tangent.org site) for orphaned song ideas
Lamar Hansford (README/INSTALL improvements) & Upload
And many many more...
2. Getting all the components
Apache >= 1.3.19 http://www.apache.org OR other webserver
PHP >= 4.1.2 http://www.php.net
PHP4-Mysql
PHP4-Session
PHP4-gd (recommended)
PHP4 ICONV & ZLIB support (recommended)
MySQL >= 3.23 http://www.mysql.com
Perl >= 5 (Optional)
16MB of Ram
3. Setting Up
Ampache:
If you're upgrading from 3.0 to 3.1 you will not be able to re-use
your database or config.php files. You will need to follow the entire
Ampache install guidelines oultined in the INSTALL file.
3a. Upgrading Your Ampache Install
If you are upgrading from an older version of Ampache we recommend
moving the old directory out of the way, extracting the new copy in
its place and then re-creating the config file. All database updates
will be handled by the /update.php script. There is no need to insert
the /sql/ampache.sql if you have an existing installation.
4. License
This Application falls under the Standard GPL. See Licence
included with this tar file
4a. Donations
We don't want your money but we will take your beer. If you
love ampache and want to encourage us to write more please
visit ampache.org for information on how to donate some beer
to our cause. If you can't send beer a postcard would also
be great. E-mail beer@ampache.org for shipping address
5. Contact Info
Hate it? Love it? Let us know. Let us know if you think of any
more features, bugs, etc.
Public SVN: https://svn.ampache.org/
IRC: irc.ampache.org #ampache (Freenode)
Forums: http://ampache.org/forums
Bugs: http://bugs.ampache.org
Demo: http://ampache.org/demo
Ampache Development Team
dev@ampache.org

114
docs/README.de Normal file
View file

@ -0,0 +1,114 @@
-------------------------------------------------------------------------------
--------- README - Ampache v.3.2 - 06/07/2004 -----------
-------------------------------------------------------------------------------
Inhalt:
1. Einleitung
a) Danksagungen
2. Komponenten herunterladen
3. Einrichten
a) Upgraden
4. Lizenz
a) Spenden (Bier!)
5. Kontaktinformationen
1. Einleitung:
Ampache stellt eine PHP-basierte Oberfläche dar, die
ihre Informationen über MP3s in einer MySQL-Datenbank ablegt.
Die Lieder werden per PHP gestreamt. Ältere Versionen erfordern
mod_mp3, aber neuere Versionen arbeiten auch ohne mod_mp3.
Die Songs werden mit Hilfe von PHP-Skripten katalogisiert.
Mit dieser Version kommen viele neue Funktionen hinzu. Es wurden
die Katalogfunktionen überarbeitet, sodass diese insbesondere auf
größeren Systemen nun einfacher zu nutzen sind. Weiterhin wurden
erste Ansätze implementiert, die es ermöglichen, die eigenen
Kataloge mit denen von anderen Ampache-Systemen zu teilen oder
gemeinsam zu nutzen. Weitere Informationen hierzu kann man im
"Katalog" Bereich bei den Administratorwerkzeugen finden.
Diese Kataloge basieren auf den ID3 Tags der MP3s. Wenn die Tags
regelmäßig gepflegt und aktuell sind, dann ist dies das geeignete
Werkzeug.
Im CHANGELOG stehen weitere Informationen zu dieser Version.
Danksagungen:
a) Dank an diejenigen, die dazu beigetragen haben, dass Ampache
das geworden ist, was es heute ist:
Scott Kveton - Hauptperson, der die Idee zu Ampache hatte
Robert Hopson - Libglue, Playlisten, Ogg Unterstützung & vieles mehr
Andy Morgan - Protagonist
Caleb Crome (Bugfixes und Verbesserungen)
Mike Payson
Jon Disnard
Adriaan Peters (Eine Vielzahl an Patches und Bugfixes)
Rob Kaandorp (Zeitberechnungsfix)
Ian Cote (MP3.php Verbesserungen)
Kurt Lieber (diverse Verbesserungen)
Maan Bsat (diverse Verbesserungen)
latka (von media.tangent.org) für die Vorschläge zur Behandlung von
Liedern ohne ID3-Tags (orphaned song)
Lamar Hansford (README/INSTALL Verbesserungen) & Upload
Und viele weitere ...
2. Komponenten herunterladen
Apache >= 1.3.19 http://www.apache.org
PHP >= 4.1.2 http://www.php.net
MySQL >= 3.23
Ampache nutzt die REPLACE Funktion von MySQL, was eine Version
von >= 3.23 erfordert.
http://www.mysql.com
16MB RAM
3. Einrichten
Ampache:
Bei einem Upgrade von Version 3.0 auf 3.1 können vorhandenen
Datenbanktabellen und die config.php nicht mehr genutzt werden.
Diese müssen in das aktuelle Format konvertiert werden. Weitere
Informationen hierzu finden sich in der INSTALL Datei.
3a. Eine vorherige Ampache-Installation upgraden
Für ein Upgrade empfiehlt sich die folgenden Vorgehenseweise:
- Eine Kopie dies alten Verzeichnisses anlegen.
-
(Falls du von einer älteren Ampache-Installation upgradest, empfehlen
wir dir, das alte Verzeichnis zu verschieben, das neue Archiv an
dieser Stelle zu entpacken und dann die config.php neu zu erstellen.
Alle Datenbankupgrades werden vom /update.php Skript erledigt.
Es ist also nicht notwendig die /sql/ampache.sql neu einzufügen,
falls bereits eine Ampache-Installation besteht.)
4. License
Ampache steht unter der Standard GPL. Nähere Informationen finden
sich in der Datei, die in diesem Archiv mitgeliefert wird.
4a. Spenden
Wir wollen euer Geld nicht, aber wir nehmen gerne euer Bier an.
Wenn dir Ampache gefällt, und du uns ermutigenn willst, das Programm
weiter zu verbessern, dann besuche ampache.org um Informationen
darüber zu bekommen, wie du uns Bier spenden kannst.
Falls das nicht möglich ist, freuen wir uns auch über eine Postkarte.
5. Kontaktinformationen
Du hasst Ampache? Du liebst es? Lass es uns wissen. Lass es uns wissen,
wenn du an neuen Features interessiert bist, Bugs melden willst usw.
IRC: irc.ampache.org #ampache (Freenode)
Foren: http://ampache.org/forums
Bugs: http://bugs.ampache.org
Ampache Development Team
ampache-dev@lists.oregonstate.edu
Karl Vollmer, Robert Hopson & Andy Morgan

61
download/index.php Normal file
View file

@ -0,0 +1,61 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Download Document
@discussion Downloads a song to the user, if they have download permission.
Special thanks to the Horde project for their Browser class that makes this so easy.
*/
require('../modules/init.php');
require(conf('prefix') . '/lib/Browser.php');
$browser = new Browser();
/* If we are running a demo, quick while you still can! */
if (conf('demo_mode') || !$user->has_access('25')) {
access_denied();
}
if ($user->prefs['download']) {
if ($_REQUEST['song_id']) {
if ($_REQUEST['action'] == 'download') {
$song = new Song($_REQUEST['song_id']);
$song->format_song();
$song->format_type();
$song_name = $song->f_artist_full . " - " . $song->title . "." . $song->type;
// Use Horde's Browser class to send the right headers for different browsers
// Should get the mime-type from the song rather than hard-coding it.
header("Content-Length: " . $song->size);
$browser->downloadHeaders($song_name, $song->mime, false, $song->size);
$fp = fopen($song->file, 'r');
fpassthru($fp);
fclose($fp);
}
}
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

55
flag.php Normal file
View file

@ -0,0 +1,55 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
This will allow users to flag songs for having broken tags or bad rips.
*/
require_once("modules/init.php");
$action = scrub_in($_REQUEST['action']);
$song = scrub_in($_REQUEST['song']);
if ( $action == 'flag_song') {
$flagged_type = scrub_in($_REQUEST['flagged_type']);
$comment = scrub_in($_REQUEST['comment']);
insert_flagged_song($song, $flagged_type, $comment);
$flag_text = _("Flagging song completed.");
$action = 'flag';
}
?>
<?php show_template('header'); ?>
<?php
$highlight = "Home";
show_menu_items($highlight);
if ( $action == 'flag' ) {
$type = 'show_flagged_form';
$song_id = $song;
include(conf('prefix') . "/templates/flag.inc");
}
show_footer();
?>
</body>
</html>

BIN
images/ampache-dark-bg.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

BIN
images/ampache-light-bg.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

BIN
images/ampache-mid.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
images/ampache.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
images/blank-pixel.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

BIN
images/blankalbum.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
images/blankalbum.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
images/headphone.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 861 B

BIN
images/table.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

139
index.php Normal file
View file

@ -0,0 +1,139 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Index of Ampache
@discussion Do most of the dirty work of displaying the mp3 catalog
*/
require_once("modules/init.php");
show_template('header');
show_menu_items('Home');
show_clear();
$action = scrub_in($_REQUEST['action']);
if (conf('refresh_limit') > 0) { show_template('javascript_refresh'); }
?>
<p style="font-size: 8pt; font-weight: bold;">
<?php echo _("Welcome to"); ?> <a href="http://www.ampache.org/index.php">Ampache v.<?php echo conf('version'); ?></a>
<?php if (conf('use_auth')) { ?>
<?php echo _("you are currently logged in as") . " " . $user->fullname ." (". $user->username .")"; ?>
<?php } ?>
<?php if (conf('theme_name')) { ?>
<!-- Theme: <?php echo conf('theme_name'); ?> (<?php echo get_theme_author(conf('theme_name')); ?>) -->
<?php } ?>
</p>
<!-- Big Daddy Table -->
<table style="padding-left:5px;padding-right:5px;padding-top:5px;padding-bottom:5px;" >
<tr>
<td style="padding-left:17px;" valign="top" colspan="2">
<?php show_now_playing(); ?>
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td valign="top">
<!-- Left table -->
<table border="0">
<tr>
<td valign="top" align="right">
<?php show_local_catalog_info(); ?>
</td>
<td valign="top" align="left">
<?php
if ( $items = get_global_popular('album') ) {
show_info_box(_("Most Popular Albums"), 'album',$items);
}
?>
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td valign="top" align="right">
<?php
if ( $items = get_global_popular('artist') ) {
show_info_box(_("Most Popular Artists"), 'artist', $items);
}
?>
</td>
<td valign="top" align="left">
<?php
if ( $items = get_global_popular('song') ) {
show_info_box(_("Most Popular Songs"), 'song', $items);
}
?>
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td valign="top" align="right">
<?php
if ( $items = get_newest('artist') ) {
show_info_box(_("Newest Artist Additions"), '', $items);
}
?>
</td>
<td valign="top" align="left">
<?php
if ( $items = get_newest('album') ) {
show_info_box(_("Newest Album Additions"), '', $items);
}
?>
</td>
</tr>
<tr><td colspan="2">&nbsp;</td></tr>
<tr>
<td colspan="2" valign="top">
<?php
show_random_play();
?>
</td>
</tr>
</table>
</td>
<td valign="top">
<!-- Right table -->
<table border="0">
<tr>
<td valign="top" rowspan="7">
<?php
if($user->prefs['play_type'] == 'local_play') {
show_local_control();
echo "<br />";
} elseif ($user->prefs['play_type'] == 'mpd') {
show_mpd_control();
echo "<br />";
} else {
echo "&nbsp;";
}
?>
</td>
</tr>
</table>
</td>
<!-- End Right Table -->
</tr>
</table>
<?php show_menu_items('Home'); ?>
</body>
</html>

1
info.php Normal file
View file

@ -0,0 +1 @@
<?php phpinfo(); ?>

132
install.php Normal file
View file

@ -0,0 +1,132 @@
<?php
/*
Copyright (c) 2001 - 2005 ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Set the Error level manualy... I'm to lazy to fix notices
error_reporting(E_ALL ^ E_NOTICE);
require_once('lib/general.php');
require_once('lib/ui.php');
require_once('lib/Browser.php');
require_once('lib/install.php');
require_once('modules/lib.php');
require_once('lib/debug.php');
require_once('modules/class/user.php');
// Libglue Requires
require_once('libglue/auth.php');
require_once('libglue/session.php');
require_once('libglue/dbh.php');
if ($_SERVER['HTTPS'] == 'on') { $http_type = "https://"; }
else { $http_type = "http://"; }
$prefix = dirname(__FILE__);
$configfile = "$prefix/config/ampache.cfg.php";
$conf_array = array('prefix' => $prefix,'font_size' => '12', 'bg_color1' => '#c0c0c0', 'font' => 'Verdana', 'error_color' => 'red');
$conf_array['base_color1'] = "#a0a0a0";
$conf_array['bg_color2'] = "#000000";
conf($conf_array);
/* First things first we must be sure that they actually still need to
install ampache
*/
if (!install_check_status($configfile)) {
access_denied();
}
/* Clean up incomming variables */
$action = scrub_in($_REQUEST['action']);
$web_path = scrub_in($_REQUEST['web_path']);
$username = scrub_in($_REQUEST['local_username']);
$password = scrub_in($_REQUEST['local_pass']);
$hostname = scrub_in($_REQUEST['local_host']);
$database = scrub_in($_REQUEST['local_db']);
/* Catch the Current Action */
switch ($action) {
case 'create_db':
if (!install_insert_db($username,$password,$hostname,$database)) {
require_once('templates/show_install.inc');
break;
}
header ("Location: " . $_SERVER['PHP_SELF'] . "?action=show_create_config&local_db=$database&local_host=$hostname");
break;
case 'create_config':
$created_config = install_create_config($web_path,$username,$password,$hostname,$database);
require_once('templates/show_install_config.inc');
break;
case 'show_create_config':
/* Attempt to Guess the Web_path */
$web_path = dirname($_SERVER['PHP_SELF']);
$web_path = rtrim($web_path,"\/");
require_once('templates/show_install_config.inc');
break;
case 'create_account':
if (!install_create_account($username,$password)) {
require_once('templates/show_install_account.inc.php');
break;
}
$results = read_config($configfile, 0, 0);
if ($_SERVER['HTTPS'] == 'on') { $http_type = "https://"; }
else { $http_type = "http://"; }
libglue_param($results['libglue']);
/* Setup Preferences */
$temp_user = new User($username);
$temp_user->fix_preferences();
$temp_user = new User(0);
$temp_user->fix_preferences();
$web_path = $http_type . $_SERVER['HTTP_HOST'] . $results['conf']['web_path'];
header ("Location: " . $web_path . "/login.php");
case 'show_create_account':
$results = read_config($configfile, 0, 0);
/* Make sure we've got a valid config file */
if (!read_config_file($configfile) OR !check_config_values($results)) {
require_once('templates/show_install_config.inc');
break;
}
require_once('templates/show_install_account.inc.php');
break;
default:
require_once('templates/show_install.inc');
break;
} // end action switch
?>

1082
lib/Browser.php Normal file

File diff suppressed because it is too large Load diff

31
lib/album.php Normal file
View file

@ -0,0 +1,31 @@
<?php
/*
This library handles album related functions.... wooo!
//FIXME: Remove this in favor of /modules/class/album
*/
/*!
@function get_albums
@discussion pass a sql statement, and it gets full album info and returns
an array of the goods.. can be set to format them as well
*/
function get_albums($sql, $action=0) {
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_array($db_results)) {
$album = new Album($r[0]);
$album->format_album();
$albums[] = $album;
}
return $albums;
} // get_albums
?>

778
lib/archive.php Normal file
View file

@ -0,0 +1,778 @@
<?php
/*--------------------------------------------------
| TAR/GZIP/BZIP2/ZIP ARCHIVE CLASSES 2.0
| By Devin Doucette
| Copyright (c) 2004 Devin Doucette
| Email: darksnoopy@shaw.ca
+--------------------------------------------------
| Email bugs/suggestions to darksnoopy@shaw.ca
+--------------------------------------------------
| This script has been created and released under
| the GNU GPL and is free to use and redistribute
| only if this copyright statement is not removed
+--------------------------------------------------*/
class archive
{
function archive($name)
{
$this->options = array(
'basedir'=>".",
'name'=>$name,
'prepend'=>"",
'inmemory'=>0,
'overwrite'=>0,
'recurse'=>1,
'storepaths'=>1,
'level'=>3,
'method'=>1,
'sfx'=>"",
'type'=>"",
'comment'=>""
);
$this->files = array();
$this->exclude = array();
$this->storeonly = array();
$this->error = array();
}
function set_options($options)
{
foreach($options as $key => $value)
{
$this->options[$key] = $value;
}
if(!empty($this->options['basedir']))
{
$this->options['basedir'] = str_replace("\\","/",$this->options['basedir']);
$this->options['basedir'] = preg_replace("/\/+/","/",$this->options['basedir']);
$this->options['basedir'] = preg_replace("/\/$/","",$this->options['basedir']);
}
if(!empty($this->options['name']))
{
$this->options['name'] = str_replace("\\","/",$this->options['name']);
$this->options['name'] = preg_replace("/\/+/","/",$this->options['name']);
}
if(!empty($this->options['prepend']))
{
$this->options['prepend'] = str_replace("\\","/",$this->options['prepend']);
$this->options['prepend'] = preg_replace("/^(\.*\/+)+/","",$this->options['prepend']);
$this->options['prepend'] = preg_replace("/\/+/","/",$this->options['prepend']);
$this->options['prepend'] = preg_replace("/\/$/","",$this->options['prepend']) . "/";
}
}
function create_archive()
{
$this->make_list();
if($this->options['inmemory'] == 0)
{
$pwd = getcwd();
chdir($this->options['basedir']);
if($this->options['overwrite'] == 0 && file_exists($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : "")))
{
$this->error[] = "File {$this->options['name']} already exists.";
chdir($pwd);
return 0;
}
else if($this->archive = @fopen($this->options['name'] . ($this->options['type'] == "gzip" || $this->options['type'] == "bzip"? ".tmp" : ""),"wb+"))
{
chdir($pwd);
}
else
{
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
}
else
{
$this->archive = "";
}
switch($this->options['type'])
{
case "zip":
if(!$this->create_zip())
{
$this->error[] = "Could not create zip file.";
return 0;
}
break;
case "bzip":
if(!$this->create_tar())
{
$this->error[] = "Could not create tar file.";
return 0;
}
if(!$this->create_bzip())
{
$this->error[] = "Could not create bzip2 file.";
return 0;
}
break;
case "gzip":
if(!$this->create_tar())
{
$this->error[] = "Could not create tar file.";
return 0;
}
if(!$this->create_gzip())
{
$this->error[] = "Could not create gzip file.";
return 0;
}
break;
case "tar":
if(!$this->create_tar())
{
$this->error[] = "Could not create tar file.";
return 0;
}
}
if($this->options['inmemory'] == 0)
{
fclose($this->archive);
if($this->options['type'] == "gzip" || $this->options['type'] == "bzip")
{
unlink($this->options['basedir'] . "/" . $this->options['name'] . ".tmp");
}
}
}
function add_data($data)
{
if($this->options['inmemory'] == 0)
{
fwrite($this->archive,$data);
}
else
{
$this->archive .= $data;
}
}
function make_list()
{
if(!empty($this->exclude))
{
foreach($this->files as $key => $value)
{
foreach($this->exclude as $current)
{
if($value['name'] == $current['name'])
{
unset($this->files[$key]);
}
}
}
}
if(!empty($this->storeonly))
{
foreach($this->files as $key => $value)
{
foreach($this->storeonly as $current)
{
if($value['name'] == $current['name'])
{
$this->files[$key]['method'] = 0;
}
}
}
}
unset($this->exclude,$this->storeonly);
}
function add_files($list)
{
$temp = $this->list_files($list);
foreach($temp as $current)
{
$this->files[] = $current;
}
}
function exclude_files($list)
{
$temp = $this->list_files($list);
foreach($temp as $current)
{
$this->exclude[] = $current;
}
}
function store_files($list)
{
$temp = $this->list_files($list);
foreach($temp as $current)
{
$this->storeonly[] = $current;
}
}
function list_files($list)
{
if(!is_array($list))
{
$temp = $list;
$list = array($temp);
unset($temp);
}
$files = array();
$pwd = getcwd();
chdir($this->options['basedir']);
foreach($list as $current)
{
$current = str_replace("\\","/",$current);
$current = preg_replace("/\/+/","/",$current);
$current = preg_replace("/\/$/","",$current);
if(strstr($current,"*"))
{
$regex = preg_replace("/([\\\^\$\.\[\]\|\(\)\?\+\{\}\/])/","\\\\\\1",$current);
$regex = str_replace("*",".*",$regex);
$dir = strstr($current,"/")? substr($current,0,strrpos($current,"/")) : ".";
$temp = $this->parse_dir($dir);
foreach($temp as $current2)
{
if(preg_match("/^{$regex}$/i",$current2['name']))
{
$files[] = $current2;
}
}
unset($regex,$dir,$temp,$current);
}
else if(@is_dir($current))
{
$temp = $this->parse_dir($current);
foreach($temp as $file)
{
$files[] = $file;
}
unset($temp,$file);
}
else if(@file_exists($current))
{
$files[] = array('name'=>$current,'name2'=>$this->options['prepend'] .
preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($current,"/"))?
substr($current,strrpos($current,"/") + 1) : $current),'type'=>0,
'ext'=>substr($current,strrpos($current,".")),'stat'=>stat($current));
}
}
chdir($pwd);
unset($current,$pwd);
usort($files,array("archive","sort_files"));
return $files;
}
function parse_dir($dirname)
{
if($this->options['storepaths'] == 1 && !preg_match("/^(\.+\/*)+$/",$dirname))
{
$files = array(array('name'=>$dirname,'name2'=>$this->options['prepend'] .
preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname,"/"))?
substr($dirname,strrpos($dirname,"/") + 1) : $dirname),'type'=>5,'stat'=>stat($dirname)));
}
else
{
$files = array();
}
$dir = @opendir($dirname);
while($file = @readdir($dir))
{
if($file == "." || $file == "..")
{
continue;
}
else if(@is_dir($dirname."/".$file))
{
if(empty($this->options['recurse']))
{
continue;
}
$temp = $this->parse_dir($dirname."/".$file);
foreach($temp as $file2)
{
$files[] = $file2;
}
}
else if(@file_exists($dirname."/".$file))
{
$files[] = array('name'=>$dirname."/".$file,'name2'=>$this->options['prepend'] .
preg_replace("/(\.+\/+)+/","",($this->options['storepaths'] == 0 && strstr($dirname."/".$file,"/"))?
substr($dirname."/".$file,strrpos($dirname."/".$file,"/") + 1) : $dirname."/".$file),'type'=>0,
'ext'=>substr($file,strrpos($file,".")),'stat'=>stat($dirname."/".$file));
}
}
@closedir($dir);
return $files;
}
function sort_files($a,$b)
{
if($a['type'] != $b['type'])
{
return $a['type'] > $b['type']? -1 : 1;
}
else if($a['type'] == 5)
{
return strcmp(strtolower($a['name']),strtolower($b['name']));
}
else
{
if($a['ext'] != $b['ext'])
{
return strcmp($a['ext'],$b['ext']);
}
else if($a['stat'][7] != $b['stat'][7])
{
return $a['stat'][7] > $b['stat'][7]? -1 : 1;
}
else
{
return strcmp(strtolower($a['name']),strtolower($b['name']));
}
}
return 0;
}
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'])
{
case "zip":
header("Content-type:application/zip");
break;
case "bzip":
header("Content-type:application/x-compressed");
break;
case "gzip":
header("Content-type:application/x-compressed");
break;
case "tar":
header("Content-type:application/x-tar");
}
$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("Pragma: no-cache");
header("Expires: 0");
print($this->archive);
}
}
class tar_file extends archive
{
function tar_file($name)
{
$this->archive($name);
$this->options['type'] = "tar";
}
function create_tar()
{
$pwd = getcwd();
chdir($this->options['basedir']);
foreach($this->files as $current)
{
if($current['name'] == $this->options['name'])
{
continue;
}
if(strlen($current['name2']) > 99)
{
$path = substr($current['name2'],0,strpos($current['name2'],"/",strlen($current['name2']) - 100) + 1);
$current['name2'] = substr($current['name2'],strlen($path));
if(strlen($path) > 154 || strlen($current['name2']) > 99)
{
$this->error[] = "Could not add {$path}{$current['name2']} to archive because the filename is too long.";
continue;
}
}
$block = pack("a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12",$current['name2'],decoct($current['stat'][2]),
sprintf("%6s ",decoct($current['stat'][4])),sprintf("%6s ",decoct($current['stat'][5])),
sprintf("%11s ",decoct($current['stat'][7])),sprintf("%11s ",decoct($current['stat'][9])),
" ",$current['type'],"","ustar","00","Unknown","Unknown","","",!empty($path)? $path : "","");
$checksum = 0;
for($i = 0; $i < 512; $i++)
{
$checksum += ord(substr($block,$i,1));
}
$checksum = pack("a8",sprintf("%6s ",decoct($checksum)));
$block = substr_replace($block,$checksum,148,8);
if($current['stat'][7] == 0)
{
$this->add_data($block);
}
else if($fp = @fopen($current['name'],"rb"))
{
$this->add_data($block);
while($temp = fread($fp,1048576))
{
$this->add_data($temp);
}
if($current['stat'][7] % 512 > 0)
{
$temp = "";
for($i = 0; $i < 512 - $current['stat'][7] % 512; $i++)
{
$temp .= "\0";
}
$this->add_data($temp);
}
fclose($fp);
}
else
{
$this->error[] = "Could not open file {$current['name']} for reading. It was not added.";
}
}
$this->add_data(pack("a512",""));
chdir($pwd);
return 1;
}
function extract_files()
{
$pwd = getcwd();
chdir($this->options['basedir']);
if($fp = $this->open_archive())
{
if($this->options['inmemory'] == 1)
{
$this->files = array();
}
while($block = fread($fp,512))
{
$temp = unpack("a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100temp/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp",$block);
$file = array(
'name'=>$temp['prefix'] . $temp['name'],
'stat'=>array(
2=>$temp['mode'],
4=>octdec($temp['uid']),
5=>octdec($temp['gid']),
7=>octdec($temp['size']),
9=>octdec($temp['mtime']),
),
'checksum'=>octdec($temp['checksum']),
'type'=>$temp['type'],
'magic'=>$temp['magic'],
);
if($file['checksum'] == 0x00000000)
{
break;
}
else if($file['magic'] != "ustar")
{
$this->error[] = "This script does not support extracting this type of tar file.";
break;
}
$block = substr_replace($block," ",148,8);
$checksum = 0;
for($i = 0; $i < 512; $i++)
{
$checksum += ord(substr($block,$i,1));
}
if($file['checksum'] != $checksum)
{
$this->error[] = "Could not extract from {$this->options['name']}, it is corrupt.";
}
if($this->options['inmemory'] == 1)
{
$file['data'] = fread($fp,$file['stat'][7]);
fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512));
unset($file['checksum'],$file['magic']);
$this->files[] = $file;
}
else
{
if($file['type'] == 5)
{
if(!is_dir($file['name']))
{
mkdir($file['name'],$file['stat'][2]);
chown($file['name'],$file['stat'][4]);
chgrp($file['name'],$file['stat'][5]);
}
}
else if($this->options['overwrite'] == 0 && file_exists($file['name']))
{
$this->error[] = "{$file['name']} already exists.";
}
else if($new = @fopen($file['name'],"wb"))
{
fwrite($new,fread($fp,$file['stat'][7]));
fread($fp,(512 - $file['stat'][7] % 512) == 512? 0 : (512 - $file['stat'][7] % 512));
fclose($new);
chmod($file['name'],$file['stat'][2]);
chown($file['name'],$file['stat'][4]);
chgrp($file['name'],$file['stat'][5]);
}
else
{
$this->error[] = "Could not open {$file['name']} for writing.";
}
}
unset($file);
}
}
else
{
$this->error[] = "Could not open file {$this->options['name']}";
}
chdir($pwd);
}
function open_archive()
{
return @fopen($this->options['name'],"rb");
}
}
class gzip_file extends tar_file
{
function gzip_file($name)
{
$this->tar_file($name);
$this->options['type'] = "gzip";
}
function create_gzip()
{
if($this->options['inmemory'] == 0)
{
$pwd = getcwd();
chdir($this->options['basedir']);
if($fp = gzopen($this->options['name'],"wb{$this->options['level']}"))
{
fseek($this->archive,0);
while($temp = fread($this->archive,1048576))
{
gzwrite($fp,$temp);
}
gzclose($fp);
chdir($pwd);
}
else
{
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
}
else
{
$this->archive = gzencode($this->archive,$this->options['level']);
}
return 1;
}
function open_archive()
{
return @gzopen($this->options['name'],"rb");
}
}
class bzip_file extends tar_file
{
function bzip_file($name)
{
$this->tar_file($name);
$this->options['type'] = "bzip";
}
function create_bzip()
{
if($this->options['inmemory'] == 0)
{
$pwd = getcwd();
chdir($this->options['basedir']);
if($fp = bzopen($this->options['name'],"wb"))
{
fseek($this->archive,0);
while($temp = fread($this->archive,1048576))
{
bzwrite($fp,$temp);
}
bzclose($fp);
chdir($pwd);
}
else
{
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
}
else
{
$this->archive = bzcompress($this->archive,$this->options['level']);
}
return 1;
}
function open_archive()
{
return @bzopen($this->options['name'],"rb");
}
}
class zip_file extends archive
{
function zip_file($name)
{
$this->archive($name);
$this->options['type'] = "zip";
}
function create_zip()
{
$files = 0;
$offset = 0;
$central = "";
if(!empty($this->options['sfx']))
{
if($fp = @fopen($this->options['sfx'],"rb"))
{
$temp = fread($fp,filesize($this->options['sfx']));
fclose($fp);
$this->add_data($temp);
$offset += strlen($temp);
unset($temp);
}
else
{
$this->error[] = "Could not open sfx module from {$this->options['sfx']}.";
}
}
$pwd = getcwd();
chdir($this->options['basedir']);
foreach($this->files as $current)
{
if($current['name'] == $this->options['name'])
{
continue;
}
$translate = array('Ç'=>pack("C",128),'ü'=>pack("C",129),'é'=>pack("C",130),'â'=>pack("C",131),'ä'=>pack("C",132),
'à'=>pack("C",133),'å'=>pack("C",134),'ç'=>pack("C",135),'ê'=>pack("C",136),'ë'=>pack("C",137),
'è'=>pack("C",138),'ï'=>pack("C",139),'î'=>pack("C",140),'ì'=>pack("C",141),'Ä'=>pack("C",142),
'Å'=>pack("C",143),'É'=>pack("C",144),'æ'=>pack("C",145),'Æ'=>pack("C",146),'ô'=>pack("C",147),
'ö'=>pack("C",148),'ò'=>pack("C",149),'û'=>pack("C",150),'ù'=>pack("C",151),'Ö'=>pack("C",153),
'Ü'=>pack("C",154),'£'=>pack("C",156),'¥'=>pack("C",157),'ƒ'=>pack("C",159),'á'=>pack("C",160),
'í'=>pack("C",161),'ó'=>pack("C",162),'ú'=>pack("C",163),'ñ'=>pack("C",164),'Ñ'=>pack("C",165));
$current['name2'] = strtr($current['name2'],$translate);
$timedate = explode(" ",date("Y n j G i s",$current['stat'][9]));
$timedate = ($timedate[0] - 1980 << 25) | ($timedate[1] << 21) | ($timedate[2] << 16) |
($timedate[3] << 11) | ($timedate[4] << 5) | ($timedate[5]);
$block = pack("VvvvV",0x04034b50,0x000A,0x0000,(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate);
if($current['stat'][7] == 0 && $current['type'] == 5)
{
$block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000);
$block .= $current['name2'] . "/";
$this->add_data($block);
$central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000,
(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate,
0x00000000,0x00000000,0x00000000,strlen($current['name2']) + 1,0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset);
$central .= $current['name2'] . "/";
$files++;
$offset += (31 + strlen($current['name2']));
}
else if($current['stat'][7] == 0)
{
$block .= pack("VVVvv",0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000);
$block .= $current['name2'];
$this->add_data($block);
$central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000,
(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate,
0x00000000,0x00000000,0x00000000,strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,$current['type'] == 5? 0x00000010 : 0x00000000,$offset);
$central .= $current['name2'];
$files++;
$offset += (30 + strlen($current['name2']));
}
else if($fp = @fopen($current['name'],"rb"))
{
$temp = fread($fp,$current['stat'][7]);
fclose($fp);
$crc32 = crc32($temp);
if(!isset($current['method']) && $this->options['method'] == 1)
{
$temp = gzcompress($temp,$this->options['level']);
$size = strlen($temp) - 6;
$temp = substr($temp,2,$size);
}
else
{
$size = strlen($temp);
}
$block .= pack("VVVvv",$crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000);
$block .= $current['name2'];
$this->add_data($block);
$this->add_data($temp);
unset($temp);
$central .= pack("VvvvvVVVVvvvvvVV",0x02014b50,0x0014,$this->options['method'] == 0? 0x0000 : 0x000A,0x0000,
(isset($current['method']) || $this->options['method'] == 0)? 0x0000 : 0x0008,$timedate,
$crc32,$size,$current['stat'][7],strlen($current['name2']),0x0000,0x0000,0x0000,0x0000,0x00000000,$offset);
$central .= $current['name2'];
$files++;
$offset += (30 + strlen($current['name2']) + $size);
}
else
{
$this->error[] = "Could not open file {$current['name']} for reading. It was not added.";
}
}
$this->add_data($central);
$this->add_data(pack("VvvvvVVv",0x06054b50,0x0000,0x0000,$files,$files,strlen($central),$offset,
!empty($this->options['comment'])? strlen($this->options['comment']) : 0x0000));
if(!empty($this->options['comment']))
{
$this->add_data($this->options['comment']);
}
chdir($pwd);
return 1;
}
} ?>

122
lib/artist.php Normal file
View file

@ -0,0 +1,122 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
This library handles all artist mojo
*/
/*!
@function get_artists
@discussion run a search, takes string,field,type and returns an array
of results of the correct type (song, album, artist)
*/
function get_artists($sql, $action=0) {
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_array($db_results)) {
$artist_info = get_artist_info($r['id']);
if ($action ==='format') { $artist = format_artist($artist_info); }
else { $artist = $artist_info; }
$artists[] = $artist;
} // end while
return $artists;
} // get_artists
/*!
@function format_artist
@discussion this function takes an array of artist
information and reformats the relevent values
so they can be displayed in a table for example
it changes the title into a full link.
*/
function format_artist($artist) {
$web_path = conf('web_path');
$artist['name'] = "<a href=\"$web_path/artists.php?action=show&amp;artist=" . $artist['id'] . "\">" . $artist['prefix'] . " " . $artist['name'] . "</a>";
return $artist;
} // format_artist
/*!
@function show_artists
@discussion takes a match and accounts for the possiblity of a view
then displays _many_ artists
*/
function show_artists ($match = '') {
global $settings;
$dbh = dbh();
$view = new View();
$view->import_session_view();
// Check for the view object...
if ($_REQUEST['keep_view']) {
$view->initialize();
}
// If there isn't a view object we need to create a new one..
else {
if ( isset($match) && $match != '' ) {
$query = "SELECT id,name FROM artist " .
" WHERE name LIKE '$match%' ";
}
else {
$query = "SELECT id FROM artist ";
}
$db_results = mysql_query($query, $dbh);
$total_items = mysql_num_rows($db_results);
if ($_REQUEST['match'] === "Show_all") {
$offset_limit = 999999;
}
else {
$offset_limit = $_SESSION['userdata']['offset_limit'];
}
$view = new View($query,'artists.php','name',$total_items,$offset_limit);
} // end if creating view object
if (is_array($match)) {
$artists = $match;
$_SESSION['view_script'] = false;
}
$db_results = mysql_query($view->sql, $dbh);
while ($r = @mysql_fetch_array($db_results)) {
$artist_info = get_artist_info($r[0]);
$artist = format_artist($artist_info);
// Only Add this artist if there is information to go along with it
if ($artist_info) {
$artists[] = $artist;
}
}
if (count($artists)) {
require ( conf('prefix') . "/templates/show_artists.inc");
}
} // show_artists
?>

63
lib/batch.php Normal file
View file

@ -0,0 +1,63 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
@function get_song_files
@discussion tmakes array of song ids and returns
array of path to actual files
@param $song_ids an array of song ids whose filenames you need
*/
function get_song_files( $song_ids ) {
global $user;
$song_files = array();
foreach( $song_ids as $song_id ) {
$song = new Song( $song_id );
/* Don't archive disabled songs */
if ($song->status != 'disabled') {
$user->update_stats( $song_id );
$total_size += sprintf("%.2f",($song->size/1048576));;
array_push( $song_files, $song->file );
} // if song isn't disabled
}
return array($song_files,$total_size);
} //get_song_files
/*!
@function send_zip
@discussion takes array of full paths to songs
zips them and sends them
@param $song_files array of full paths to songs to zip
create w/ call to get_song_files
*/
function send_zip( $name, $song_files ) {
require_once(conf('prefix') . '/lib/archive.php' );
$arc = new zip_file( $name . ".zip" );
$options = array(
'inmemory' => 1, // create archive in memory
'storepaths' => 0, // only store file name, not full path
'level' => 0 // no compression
);
$arc->set_options( $options );
$arc->add_files( $song_files );
$arc->create_archive();
$arc->download_file();
}
?>

361
lib/debug.php Normal file
View file

@ -0,0 +1,361 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
@header Debug Library
This library is loaded when somehow our mojo has
been lost, it contains functions for checking sql
connections, web paths etc..
*/
/*!
@function read_config_file
@discussion checks to see if the config
file is readable, overkill I know..
@param level 0 is readable, 1 detailed info
*/
function read_config_file($file,$level=0) {
$fp = @fopen($file, 'r');
if (!$level) {
return is_resource($fp);
}
} // read_config_file
/*!
@function check_database
@discussion checks the local mysql db
and make sure life is good
*/
function check_database($host,$username,$pass,$db,$level=0) {
$dbh = @mysql_connect($host, $username, $pass);
if (!is_resource($dbh)) {
$error['error_state'] = true;
$error['mysql_error'] = mysql_errno() . ": " . mysql_error() . "\n";
}
if (!$host || !$username || !$pass) {
$error['error_state'] = true;
$error['mysql_error'] .= "<br />HOST:$host<br />User:$username<br />Pass:$pass<br />";
}
print_r($error);
if ($error['error_state']) { return false; }
return $dbh;
} // check_database
/*!
@function check_database_inserted
@discussion checks to make sure that you
have inserted the database and that the user
you are using has access to it
*/
function check_database_inserted($dbh,$db_name) {
if (!@mysql_select_db($db_name,$dbh)) {
return false;
}
$sql = "DESCRIBE session";
$db_results = @mysql_query($sql, $dbh);
if (!@mysql_num_rows($db_results)) {
return false;
}
return true;
} // check_database_inserted
/*!
@function check_php_ver
@discussion checks the php version and makes
sure that it's good enough
*/
function check_php_ver($level=0) {
if (strcmp('4.1.2',phpversion()) > 0) {
$error['error_state'] = true;
$error['php_ver'] = phpversion();
}
if ($error['error_state']) { return false; }
return true;
} // check_php_ver
/*!
@function check_php_mysql
@discussion checks for mysql support
*/
function check_php_mysql() {
if (!function_exists('mysql_query')) {
$error['error_state'] = true;
$error['php_mysql'] = false;
}
if ($error['error_state']) { return false; }
return true;
} // check_php_mysql
/*!
@function check_php_session
@discussion checks to make sure the needed functions
for sessions exist
*/
function check_php_session() {
if (!function_exists('session_set_save_handler')) {
$error['error_state'] = true;
$error['php_session'] = false;
}
if ($error['error_state']) { return false; }
return true;
} // check_php_session
/*!
@function check_php_iconv
@discussion checks to see if you have iconv installed
*/
function check_php_iconv() {
if (!function_exists('iconv')) {
$error['error_state'] = true;
$error['php_iconv'] = false;
}
if ($error['error_state']) { return false; }
return true;
} // check_php_iconv
/*!
@function check_config_values()
@discussion checks to make sure that they have at
least set the needed variables
*/
function check_config_values($conf) {
if (!$conf['libglue']['local_host']) {
return false;
}
if (!$conf['libglue']['local_db']) {
return false;
}
if (!$conf['libglue']['local_username']) {
return false;
}
if (!$conf['libglue']['local_pass']) {
return false;
}
if (!$conf['libglue']['local_length']) {
return false;
}
return true;
} // check_config_values
/*!
@function show_compare_config
@discussion shows the difference between ampache.cfg
and ampache.cfg.dst
*/
function show_compare_config($prefix) {
// Live Config File
$live_config = $prefix . "/config/ampache.cfg.php";
// Generic Config File
$generic_config = $prefix . "/config/ampache.cfg.dist";
} // show_compare_config
/*!
@function debug_read_config
@discussion this is the same as the read config function
except it will pull config values with a # before them
(basicly adding a #config="value" check) and not
ever dieing on a config file error
*/
function debug_read_config($config_file,$debug) {
$fp = @fopen($config_file,'r');
if(!is_resource($fp)) return false;
$file_data = fread($fp,filesize($config_file));
fclose($fp);
// explode the var by \n's
$data = explode("\n",$file_data);
if($debug) echo "<pre>";
$count = 0;
foreach($data as $value) {
$count++;
$value = trim($value);
if (preg_match("/^\[([A-Za-z]+)\]$/",$value,$matches)) {
// If we have previous data put it into $results...
if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) {
$results[$config_name] = ${$config_name};
}
$config_name = $matches[1];
} // if it is a [section] name
elseif (isset($config_name)) {
// if it's not a comment
if (preg_match("/^#?([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches)
|| preg_match("/^#?([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches)
|| preg_match("/^#?([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) {
if (isset(${$config_name}[$matches[1]]) && is_array(${$config_name}[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push(${$config_name}[$matches[1]], $matches[2]);
}
elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "") {
if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
${$config_name}[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) {
echo "Error Invalid Config Entry --> Line:$count"; return false;
} // elseif it's not a comment and there is something there
else {
if($debug) echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end if it's not a comment
} // elseif no config_name
elseif (preg_match("/^#?([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches)
|| preg_match("/^#?([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches)
|| preg_match("/^#?([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) {
if (is_array($results[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push($results[$matches[1]], $matches[2]);
}
elseif (isset($results[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
$results[$matches[1]] = array($results[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "") {
if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
$results[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) {
echo "Error Invalid Config Entry --> Line:$count"; return false;
} // elseif it's not a comment and there is something there
else {
if($debug) echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end else
} // foreach
if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) {
$results[$config_name] = ${$config_name};
}
if($debug) echo "</pre>";
return $results;
} // debug_read_config
/*!
@function debug_compare_configs
@discussion this takes two config files, and then compares
the results and returns an array of the values
that are missing from the first one passed
*/
function debug_compare_configs($config,$dist_config) {
/* Get the results from the two difference configs including #'d values */
$results = debug_read_config($config,0);
$dist_results = debug_read_config($dist_config,0);
$missing = array();
if (!count($dist_results['conf'])) { $dist_results['conf'] = array(); }
if (!count($dist_results['libglue'])) { $dist_results['libglue'] = array(); }
foreach ($dist_results['conf'] as $key=>$value) {
if (!isset($results['conf'][$key])) {
$missing['conf'][$key] = $value;
}
} // end foreach conf
foreach ($dist_results['libglue'] as $key=>$value) {
if (!isset($results['libglue'][$key])) {
$missing['libglue'][$key] = $value;
}
} // end foreach libglue
return $missing;
} // debug_compare_configs
?>

117
lib/duplicates.php Normal file
View file

@ -0,0 +1,117 @@
<?php
/*!
@header Contains the functions for handling duplicate songs
*/
/*!
@function get_duplicate_songs
@discussion
*/
function get_duplicate_songs($search_type) {
$sql = "SELECT song.id as song,artist.name,album.name,title,count(title) as ctitle".
" FROM song,artist,album ".
" WHERE song.artist=artist.id AND song.album=album.id AND song.title<>'' ".
" GROUP BY title";
if ($search_type=="artist_title"||$search_type=="artist_album_title")
$sql = $sql.",artist";
if ($search_type=="artist_album_title")
$sql = $sql.",album";
$sql = $sql." HAVING count(title) > 1";
$sql = $sql." ORDER BY ctitle";
//echo $sql."<BR>";
$result = mysql_query($sql, dbh());
$arr = array();
while ($flag = mysql_fetch_array($result)) {
$arr[] = $flag;
} // end while
return $arr;
} // get_duplicate_songs
/*!
@function get_duplicate_info
@discussion
*/
function get_duplicate_info($song,$search_type) {
$artist = get_artist_name($song->artist);
$sql = "SELECT song.id as songid,song.title as song,file,bitrate,size,time,album.name AS album,album.id as albumid, artist.name AS artist,artist.id as artistid".
" FROM song,artist,album ".
" WHERE song.artist=artist.id AND song.album=album.id ".
" AND song.title= '".str_replace("'","''",$song->title)."'";
if ($search_type=="artist_title"||$search_type=="artist_album_title")
$sql = $sql." AND artist.id = '".$song->artist."'";
if ($search_type=="artist_album_title")
$sql = $sql." AND album.id = '".$song->album."'";
$result = mysql_query($sql, dbh());
$arr = array();
while ($flag = mysql_fetch_array($result)) {
$arr[] = $flag;
} // end while
return $arr;
} // get_duplicate_info
/*!
@function show_duplicate_songs
@discussion
*/
function show_duplicate_songs($flags,$search_type) {
require_once(conf('prefix').'/templates/list_duplicates.inc');
} // show_duplicate_songs
/*!
@function show_duplicate_searchbox
@discussion
*/
function show_duplicate_searchbox($search_type) {
?>
<br />
<form name="songs" action="<?php echo conf('web_path'); ?>/admin/duplicates.php" method="post" enctype="multipart/form-data" >
<table class="border" cellspacing="0" cellpadding="3" border="0" width="450px">
<tr class="table-header">
<td colspan="2"><b><?php echo _("Find Duplicates"); ?></b></td>
</tr>
<tr class="even">
<td><?php echo _("Search Type"); ?>:</td>
<td>
<?
if ($search_type=="title")
$checked = "checked=\"checked\"";
else
$checked = "";
echo "<input type=\"radio\" name=\"search_type\" value=\"title\" ".$checked." >" . _("Title") . "<br />";
if ($search_type=="artist_title")
$checked = "checked=\"checked\"";
else
$checked = "";
echo "<input type=\"radio\" name=\"search_type\" value=\"artist_title\" ".$checked." >" . _("Artist and Title") . "<br />";
if ($search_type=="artist_album_title"OR $search_type=="")
$checked = "checked=\"checked\"";
else
$checked = "";
echo "<input type=\"radio\" name=\"search_type\" value=\"artist_album_title\"".$checked." >" . _("Artist, Album and Title") . "<br />";
?>
</td>
</tr>
<tr class="odd">
<td></td>
<td>
<input type="hidden" name="action" value="search">
<input type="submit" value="<?php echo _("Search"); ?>" />
</td>
</tr>
</table>
<br>
<?
} // show_duplicate_searchbox
?>

348
lib/flag.php Normal file
View file

@ -0,0 +1,348 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
//
//
function add_to_edit_queue($flags=0)
{
$oldflags = 0;
if(empty($flags)) $flags = 0;
if($_SESSION['edit_queue'])
{
$oldflags = $_SESSION['edit_queue'];
if(!is_array($oldflags)) $oldflags = array($oldflags);
}
if(!is_array($flags))
{
if($flags !== 0) $flags = array($flags);
}
if(is_array($flags))
{
if(is_array($oldflags)) $new_array = array_merge($flags, $oldflags);
else $new_array = $flags;
}
elseif (is_array($oldflags)) $new_array = $oldflags;
if(count($new_array))
{
$_SESSION['edit_queue'] = $new_array;
return count($new_array);
}
else
{
unset($_SESSION['edit_queue']);
return 0;
}
}
function show_edit_flagged($flag=0)
{
if(empty($flag)||$flag === 0)
{
$flag = array_pop($_SESSION['edit_queue']);
}
$flaginfo = get_flag($flag);
if($flaginfo['type'] === 'badid3')
{
show_edit_badid3($flaginfo['song'],$flag);
}
else
{
echo "I don't know how to edit already edited songs yet: $flag.<br />";
}
}
function show_edit_badid3($songid,$flagid)
{
$song = get_song_info($songid);
require(conf('prefix')."/templates/song_edit.inc");
}
function get_flag($id)
{
if(!is_array($id)) $id = array($id);
$results = array();
$newid = array_pop($id);
$sql = "SELECT flagged.id,user.username,type,song,date,comment" .
" FROM flagged,user WHERE flagged.user = user.id AND (flagged.song = '$newid'";
foreach($id as $num)
{
$sql .= " OR flagged.song = '$num'";
}
$sql .= ")";
$result = mysql_query($sql, dbh());
while ($row = mysql_fetch_array($result))
{
$results[] = $row;
}
if(count($results) == 1) return $results[0];
else return $results;
}
function get_flagged_songs($user = 0)
{
$sql = "SELECT flagged.id,user.username,type,song,date,comment" .
" FROM flagged,user WHERE flagged.user = user.id AND flagged.type <> 'notify' AND flagged.type <> 'done'";
// If the user is not an admin, they can only see songs they've flagged
if($user)
{
if($_SESSION['userdata']['access'] === 'admin')
{
$sql .= " AND user.id = '$user'";
}
else
{
$sql .= " AND user.id = '".$_SESSION['userdata']['id']."'";
}
}
$sql .= " ORDER BY date";
$result = mysql_query($sql, dbh());
$arr = array();
while ($flag = mysql_fetch_array($result))
{
$arr[] = $flag;
}
return $arr;
}
function show_flagged_songs($flags)
{
require_once(conf('prefix').'/templates/list_flagged.inc');
}
function accept_new_tags($flags)
{
if(!is_array($flags)) $flags = array($flags);
foreach($flags as $flag)
{
copy_updated_tag($flag);
}
set_flag_value($flags, 'setid3');
}
function reject_new_tags($flags)
{
if(!is_array($flags)) $flags = array($flags);
$oldflags = $flags;
$flag = array_pop($flags);
$sql = "DELETE FROM flagged_songs WHERE song = '$flag'";
foreach($flags as $flag)
{
$sql .= " OR song = '$flag'";
}
$result = mysql_query($sql, dbh());
$user = $_SESSION['userdata']['username'];
set_flag_value($oldflags, 'notify', "Tag changes rejected by $user");
}
function set_flag_value($flags, $val, $comment = '')
{
if(!is_array($flags)) $flags = array($flags);
$user = $_SESSION['userdata']['id'];
/* $flagid = array_pop($flags);*/
$dbh = dbh();
foreach($flags as $flagid)
{
$sql = "REPLACE INTO flagged (type,song,comment,user,date)".
" VALUES ('$val','$flagid','$comment','$user','".time()."')";
$result = mysql_query($sql, $dbh);
}
return $result;
}
function copy_updated_tag($flag)
{
$flagdata = get_flag($flag);
$sql = "SELECT * FROM flagged_song WHERE song = '".$flagdata['song']."'";
$result = mysql_query($sql, dbh());
$newtag = mysql_fetch_array($result);
if($newtag['new_artist'])
{
$newtag['artist'] = insert_artist($newtag['new_artist']);
}
if($newtag['new_album'])
{
$newtag['album'] = insert_album($newtag['new_album']);
}
$sql = "UPDATE song SET ".
"title = '".$newtag['title']."',".
"artist = '".$newtag['artist']."',".
"album = '".$newtag['album']."',".
"track = '".$newtag['track']."',".
"genre = '".$newtag['genre']."',".
"year = '".$newtag['year']."' ".
"WHERE song.id = '".$newtag['song']."'";
$result = mysql_query($sql, dbh());
if($result)
{
$sql2 = "DELETE FROM flagged_song WHERE song='".$flagdata['song']."'";
$result2 = mysql_query($sql2, dbh());
}
return ($result && $result2);
}
function update_flags($songs)
{
$accepted = array();
$rejected = array();
$newflags = array();
foreach($songs as $song)
{
$accept = scrub_in($_REQUEST[$song.'_accept']);
if($accept === 'accept') $accepted[] = $song;
elseif ($accept === 'reject') $rejected[] = $song;
else
{
$newflag = scrub_in($_REQUEST[$song.'_newflag']);
$newflags[$song] = $newflag;
}
}
if(count($accepted))
{
accept_new_tags($accepted);
}
if(count($rejected))
{
reject_new_tags($rejected);
}
if(count($newflags))
{
foreach($newflags as $flag=>$type)
{
set_flag_value($flag, $type);
}
}
}
function update_song_info($song)
{
$user = $_SESSION['userdata'];
$title = scrub_in($_REQUEST['title']);
$track = scrub_in($_REQUEST['track']);
$genre = scrub_in($_REQUEST['genre']);
$year = scrub_in($_REQUEST['year']);
if(isset($_REQUEST['update_id3']))
$update_id3 = 1;
if(isset($_REQUEST['new_artist']) && $_REQUEST['new_artist'] !== '')
{
$create_artist = 1;
$artist = scrub_in($_REQUEST['new_artist']);
}
else
$artist = scrub_in($_REQUEST['artist']);
if(isset($_REQUEST['new_album']) && $_REQUEST['new_album'] !== '')
{
$create_album = 1;
$album = scrub_in($_REQUEST['new_album']);
}
else
$album = scrub_in($_REQUEST['album']);
if(is_array($_REQUEST['genre'])) {
$genre = $genre[0];
}
if($user['access'] == 'admin')
// Update the file directly
{
if($create_artist)
{
$artist = insert_artist($artist);
}
if($create_album)
{
$album = insert_album($album);
}
// Escape data (prevent " or ' snafu's)
$title = sql_escape($title);
$artist = sql_escape($artist);
$album = sql_escape($album);
$genre = sql_escape($genre);
$year = sql_escape($year);
$sql = "UPDATE song SET" .
" title = '$title'," .
" track = '$track'," .
" genre = '$genre'," .
" year = '$year'," .
" artist = '$artist',".
" album = '$album'," .
" update_time = '".time()."'" .
" WHERE id = '$song' LIMIT 1";
$result = mysql_query($sql, dbh() );
if($result && $update_id3 )
{
//Add to flagged table so we can fix the id3 tags
$date = time();
$sql = "REPLACE INTO flagged SET " .
" type = 'setid3', song = '$song', date = '$date', user = '".$user['id']."'";
$result = mysql_query($sql, dbh());
}
}
else
// Stick in the flagged_songs table to be updated by an admin
{
if($create_artist) $artist_field = 'new_artist';
else $artist_field = 'artist';
if($create_album) $album_field = 'new_album';
else $album_field = 'album';
$sql = "INSERT INTO flagged_song(song,title,track,genre,year,$artist_field,$album_field,update_time) " .
"VALUES ('$song','$title','$track','$genre','$year','$artist','$album','".time()."')";
$result = mysql_query($sql, dbh() );
if($result && $update_id3 )
{
//Add to flagged table so we can fix the id3 tags
$date = time();
$sql = "REPLACE INTO flagged SET " .
" type = 'newid3', song = '$song', date = '$date', user = '".$user['id']."'";
$result = mysql_query($sql, dbh());
}
echo "Thanks for helping to keep the catalog up to date. Someone will review your changes, and you will be notified on the main page when they're approved.";
}
}

554
lib/general.php Normal file
View file

@ -0,0 +1,554 @@
<?php
/*
@header General Library
This is the general library that contains misc functions
that doesn't have a home elsewhere
*/
/*!
@function sql_escape
@discussion this takes a sql statement
and properly escapes it before a query is run
against it.
*/
function sql_escape($sql,$dbh=0) {
if (!is_resource($dbh)) {
$dbh = dbh();
}
if (function_exists('mysql_real_escape_string')) {
$sql = mysql_real_escape_string($sql,$dbh);
}
else {
$sql = mysql_escape_string($sql);
}
return $sql;
} // sql_escape
/*!
@function ip2int
@discussion turns a dotted quad ip into an
int
*/
function ip2int($ip) {
$a=explode(".",$ip);
return $a[0]*256*256*256+$a[1]*256*256+$a[2]*256+$a[3];
} // ip2int
/*!
@function int2ip
@discussion turns a int into a dotted quad
*/
function int2ip($i) {
$d[0]=(int)($i/256/256/256);
$d[1]=(int)(($i-$d[0]*256*256*256)/256/256);
$d[2]=(int)(($i-$d[0]*256*256*256-$d[1]*256*256)/256);
$d[3]=$i-$d[0]*256*256*256-$d[1]*256*256-$d[2]*256;
return "$d[0].$d[1].$d[2].$d[3]";
} // int2ip
/*!
@function show_template
@discussion show a template from the /templates directory, automaticly appends .inc
to the passed filename
@param $template Name of Template
*/
function show_template($template) {
/* Check for a 'Theme' template */
if (is_readable(conf('prefix') . conf('theme_path') . "/templates/$template".".inc")) {
require (conf('prefix') . conf('theme_path') . "/templates/$template".".inc");
}
else {
require (conf('prefix') . "/templates/$template".".inc");
}
} // show_template
/*!
@function read_config
@discussion reads the config file for ampache
*/
function read_config($config_file, $debug=0, $test=0) {
$fp = @fopen($config_file,'r');
if(!is_resource($fp)) return false;
$file_data = fread($fp,filesize($config_file));
fclose($fp);
// explode the var by \n's
$data = explode("\n",$file_data);
if($debug) echo "<pre>";
$count = 0;
foreach($data as $value) {
$count++;
$value = trim($value);
if (preg_match("/^\[([A-Za-z]+)\]$/",$value,$matches)) {
// If we have previous data put it into $results...
if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) {
$results[$config_name] = ${$config_name};
}
$config_name = $matches[1];
} // if it is a [section] name
elseif (isset($config_name)) {
// if it's not a comment
if (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) {
if (isset(${$config_name}[$matches[1]]) && is_array(${$config_name}[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push(${$config_name}[$matches[1]], $matches[2]);
}
elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "") {
if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
${$config_name}[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) {
echo "Error Invalid Config Entry --> Line:$count"; return false;
} // elseif it's not a comment and there is something there
else {
if($debug) echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end if it's not a comment
} // elseif no config_name
elseif (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches)) {
if (is_array($results[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push($results[$matches[1]], $matches[2]);
}
elseif (isset($results[$matches[1]]) && isset($matches[2]) ) {
if($debug) echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
$results[$matches[1]] = array($results[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "") {
if($debug) echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
$results[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0 AND !$test AND strlen($matches[2]) > 0) {
echo "Error Invalid Config Entry --> Line:$count"; return false;
} // elseif it's not a comment and there is something there
else {
if($debug) echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end else
} // foreach
if (isset($config_name) && isset(${$config_name}) && count(${$config_name})) {
$results[$config_name] = ${$config_name};
}
if($debug) echo "</pre>";
return $results;
} // read_config
/*
* Conf function by Robert Hopson
* call it with a $parm name to retrieve
* a var, pass it a array to set them
* to reset a var pass the array plus
* Clobber! replaces global $conf;
*/
function conf($param,$clobber=0)
{
static $params = array();
if(is_array($param))
//meaning we are setting values
{
foreach ($param as $key=>$val)
{
if(!$clobber && isset($params[$key]))
{
echo "Error: attempting to clobber $key = $val\n";
exit();
}
$params[$key] = $val;
}
return true;
}
else
//meaning we are trying to retrieve a parameter
{
if($params[$param]) return $params[$param];
else return;
}
} //conf
function libglue_param($param,$clobber=0)
{
static $params = array();
if(is_array($param))
//meaning we are setting values
{
foreach ($param as $key=>$val)
{
if(!$clobber && isset($params[$key]))
{
echo "Error: attempting to clobber $key = $val\n";
exit();
}
$params[$key] = $val;
}
return true;
}
else
//meaning we are trying to retrieve a parameter
{
if(isset($params[$param])) return $params[$param];
else return false;
}
}
function error_results($param,$clobber=0)
{
static $params = array();
if(is_array($param))
//meaning we are setting values
{
foreach ($param as $key=>$val)
{
if(!$clobber && isset($params[$key]))
{
echo "Error: attempting to clobber $key = $val\n";
exit();
}
$params[$key] = $val;
}
return true;
}
else
//meaning we are trying to retrieve a parameter
{
if($params[$param]) return $params[$param];
else return;
}
} //error_results
/*!
@function dbh
@discussion retrieves the DBH
*/
function dbh() { return check_sess_db('local'); }
/*!
@function fix_preferences
@discussion cleans up the preferences
*/
function fix_preferences($results) {
foreach ($results as $key=>$data) {
if (strcasecmp($data, "yes") == "0") { $data = 1; }
if (strcasecmp($data,"true") == "0") { $data = 1; }
if (strcasecmp($data,"enabled") == "0") { $data = 1; }
if (strcasecmp($data,"disabled") == "0") { $data = 0; }
if (strcasecmp($data,"false") == "0") { $data = 0; }
if (strcasecmp($data,"no") == "0") { $data = 0; }
$results[$key] = $data;
}
return $results;
} // fix_preferences
/*!
@function session_exists
@discussion checks to make sure they've specified a
valid session
*/
function session_exists($sid) {
$sql = "SELECT * FROM session WHERE id = '$sid'";
$db_results = mysql_query($sql, dbh());
if (!mysql_num_rows($db_results)) {
return false;
}
return true;
} // session_exists
/*!
@function extend_session
@discussion just update the expire time
*/
function extend_session($sid) {
$new_time = time() + conf('local_length');
if ($_COOKIE['amp_longsess'] == '1') { $new_time = time() + 86400*364; }
$sql = "UPDATE session SET expire='$new_time' WHERE id='$sid'";
$db_results = mysql_query($sql, dbh());
} // extend_session
/*!
@function get_tag_type
@discussion finds out what tag the audioinfo
results returned
*/
function get_tag_type($results) {
// Check and see if we are dealing with an ogg
// If so order will be a little different
if ($results['ogg']) {
$order[0] = 'ogg';
} // end if ogg
elseif ($results['rm']) {
$order[0] = 'rm';
}
elseif ($results['flac']) {
$order[0] = 'flac';
}
elseif ($results['asf']) {
$order[0] = 'asf';
}
elseif ($results['m4a']) {
$order[0] = 'm4a';
}
elseif ($results['mpc']) {
$order[0] = 'mpc';
}
else {
$order = conf('id3tag_order');
} // end else
if (!is_array($order)) {
$order = array($order);
}
// set the $key to the first found tag style (according to their prefs)
foreach($order as $key) {
if ($results[$key]) {
break;
}
}
return $key;
} // get_tag_type
/*!
@function clean_tag_info
@discussion cleans up the tag information
*/
function clean_tag_info($results,$key,$filename) {
$info = array();
$clean_array = array("\n","\t","\r","\0");
$wipe_array = array("","","","");
$info['file'] = $filename;
$info['title'] = stripslashes(trim($results[$key]['title']));
$info['year'] = intval($results[$key]['year']);
$info['comment'] = sql_escape(str_replace($clean_array,$wipe_array,$results[$key]['comment']));
$info['bitrate'] = intval($results['avg_bit_rate']);
$info['rate'] = intval($results['sample_rate']);
$info['mode'] = $results['bitrate_mode'];
$info['size'] = filesize($filename);
$info['time'] = intval($results['playing_time']);
$info['track'] = intval($results[$key]['track']);
/* These are used to generate the correct ID's later */
$info['artist'] = trim($results[$key]['artist']);
$info['album'] = trim($results[$key]['album']);
$info['genre'] = trim($results[$key]['genre']);
return $info;
} // clean_tag_info
/*!
@function scrub_in()
@discussion Run on inputs, stuff that might get stuck in our db
*/
function scrub_in($str) {
if (!is_array($str)) {
return stripslashes( htmlspecialchars( strip_tags($str) ) );
}
else {
$ret = array();
foreach($str as $string) $ret[] = scrub_in($string);
return $ret;
}
} // scrub_in
/*!
@function batch_ok()
@discussion return boolean if user can batch download
*/
function batch_ok( ) {
global $user;
// i check this before showing any link
// should make it easy to tie to a new pref if you choose to add it
if (conf('allow_zip_download')) {
return( $user->prefs['download'] );
} // if allowed zip downloads
return false;
} // batch_ok
/*!
@function set_memory_limit
@discussion this function attempts to change the
php memory limit using init_set but it will
never reduce it
*/
function set_memory_limit($new_limit) {
/* Check their PHP Vars to make sure we're cool here */
// Up the memory
$current_memory = ini_get('memory_limit');
$current_memory = substr($current_memory,0,strlen($current_memory)-1);
if ($current_memory < $new_limit) {
$php_memory = $new_limit . "M";
ini_set (memory_limit, "$php_memory");
unset($php_memory);
}
} // set_memory_limit
/*!
@function get_random_songs
@discussion Returns a random set of songs/albums or artists
matchlist is an array of the WHERE mojo and options
defines special unplayed,album,artist,limit info
*/
function get_random_songs( $options, $matchlist) {
$dbh = dbh();
/* Define the options */
$limit = $options['limit'];
$unplayed = $options['unplayed'];
/* If they've passed -1 as limit then don't get everything */
if ($options['limit'] == "-1") { unset($options['limit']); }
else { $options['limit'] = "LIMIT " . $limit; }
$where = "1=1 ";
if(is_array($matchlist))
foreach ($matchlist as $type => $value) {
if (is_array($value)) {
foreach ($value as $v) {
$v = sql_escape($v);
if ($v != $value[0]) { $where .= " OR $type='$v' "; }
else { $where .= " AND ( $type='$v'"; }
}
$where .= " ) ";
}
else {
$value = sql_escape($value);
$where .= " AND $type='$value' ";
}
}
if ($options['full_album'] == 1) {
$query = "SELECT album.id FROM song,album WHERE song.album=album.id AND $where GROUP BY song.album ORDER BY RAND() " . $options['limit'];
$db_results = mysql_query($query, $dbh);
while ($data = mysql_fetch_row($db_results)) {
$albums_where .= " OR song.album=" . $data[0];
}
$albums_where = ltrim($albums_where," OR");
$query = "SELECT song.id FROM song WHERE $albums_where ORDER BY song.track ASC";
}
elseif ($options['full_artist'] == 1) {
$query = "SELECT artist.id FROM song,artist WHERE song.artist=artist.id AND $where GROUP BY song.artist ORDER BY RAND() " . $options['limit'];
$db_results = mysql_query($query, $dbh);
while ($data = mysql_fetch_row($db_results)) {
$artists_where .= " OR song.artist=" . $data[0];
}
$artists_where = ltrim($artists_where," OR");
$query = "SELECT song.id FROM song WHERE $artists_where ORDER BY RAND()";
}
elseif ($options['unplayed'] == 1) {
$uid = $_SESSION['userdata']['id'];
$query = "SELECT song.id FROM song LEFT JOIN object_count ON song.id = object_count.object_id " .
"WHERE ($where) AND ((object_count.object_type='song' AND userid = '$uid') OR object_count.count IS NULL ) " .
"ORDER BY CASE WHEN object_count.count IS NULL THEN RAND() WHEN object_count.count > 4 THEN RAND()*RAND()*object_count.count " .
"ELSE RAND()*object_count.count END " . $options['limit'];
} // If unplayed
else {
$query = "SELECT id FROM song WHERE $where ORDER BY RAND() " . $options['limit'];
}
$db_result = mysql_query($query, $dbh);
$songs = array();
while ( $r = mysql_fetch_array($db_result) ) {
$songs[] = $r[0];
}
return ($songs);
} // get_random_songs
/*!
@function cleanup_and_exit
@discussion used specificly for the play/index.php file
this functions nukes now playing and then exits
*/
function cleanup_and_exit($playing_id) {
/* Clear now playing */
// 900 = 15 min
$expire = time() - 900;
$sql = "DELETE FROM now_playing WHERE id='$lastid' OR start_time < $expire";
$db_results = mysql_query($sql, dbh());
exit();
} // cleanup_and_exit
?>

36
lib/gettext.php Normal file
View file

@ -0,0 +1,36 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@function load_gettext
@discussion sets the local
*/
function load_gettext() {
/* If we have gettext */
if (function_exists('bindtextdomain')) {
bindtextdomain('messages', conf('prefix') . "/locale/");
textdomain('messages');
putenv("LANG=" . conf('lang'));
setlocale(LC_ALL, conf('lang'));
}
} // load_gettext
?>

238
lib/install.php Normal file
View file

@ -0,0 +1,238 @@
<?
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Install docuement
@discussion this document contains the functions needed to see if
ampache needs to be installed
*/
/*!
@function split_sql
@discussion splits up a standard SQL dump file into distinct
sql queryies
*/
function split_sql($sql) {
$sql = trim($sql);
$sql = ereg_replace("\n#[^\n]*\n", "\n", $sql);
$buffer = array();
$ret = array();
$in_string = false;
for($i=0; $i<strlen($sql)-1; $i++) {
if($sql[$i] == ";" && !$in_string) {
$ret[] = substr($sql, 0, $i);
$sql = substr($sql, $i + 1);
$i = 0;
}
if($in_string && ($sql[$i] == $in_string) && $buffer[1] != "\\") {
$in_string = false;
}
elseif(!$in_string && ($sql[$i] == '"' || $sql[$i] == "'") && (!isset($buffer[0]) || $buffer[0] != "\\")) {
$in_string = $sql[$i];
}
if(isset($buffer[1])) {
$buffer[0] = $buffer[1];
}
$buffer[1] = $sql[$i];
}
if(!empty($sql)) {
$ret[] = $sql;
}
return($ret);
} // split_sql
/*!
@function install_check_status()
@discussion this function checks to see if we actually
still need to install ampache. This function is
very important, we don't want to reinstall over top
of an existing install
*/
function install_check_status($configfile) {
/*
Check and see if the config file exists
if it does they can't use the web interface
to install ampache.
*/
if (!file_exists($configfile)) {
return true;
}
/*
Check and see if they've got _any_ account
if they don't then they're cool
*/
$results = read_config($GLOBALS['configfile'], 0, 0);
$dbh = check_database($results['libglue']['local_host'],$results['libglue']['local_username'],$results['libglue']['local_pass'],$results['libglue']['local_db']);
if (is_resource($dbh)) {
mysql_select_db($results['libglue']['local_db'],$dbh);
$sql = "SELECT * FROM user";
$db_results = @mysql_query($sql, $dbh);
if (!@mysql_num_rows($db_results)) {
return true;
}
}
/* Defaut to no */
return false;
} // install_check_status
/*!
@function install_insert_db()
@discussion this function inserts the database
using the username/pass/host provided
and reading the .sql file
*/
function install_insert_db($username,$password,$hostname,$database) {
/* Attempt to make DB connection */
$dbh = @mysql_pconnect($hostname,$username,$password);
/* Check/Create Database as needed */
$db_selected = @mysql_select_db($database, $dbh);
if (!$db_selected) {
$sql = "CREATE DATABASE `" . $database . "`";
if (!$db_results = @mysql_query($sql, $dbh)) {
return false;
}
@mysql_select_db($database, $dbh);
} // if db can't be selected
/* Attempt to insert database */
$query = fread(fopen("sql/ampache.sql", "r"), filesize("sql/ampache.sql"));
$pieces = split_sql($query);
for ($i=0; $i<count($pieces); $i++) {
$pieces[$i] = trim($pieces[$i]);
if(!empty($pieces[$i]) && $pieces[$i] != "#") {
//FIXME: This is for a DB prefix when we get around to it
// $pieces[$i] = str_replace( "#__", $DBPrefix, $pieces[$i]);
if (!$result = mysql_query ($pieces[$i])) {
$errors[] = array ( mysql_error(), $pieces[$i] );
} // end if
} // end if
} // end for
return true;
} // install_insert_db
/*!
@function install_create_config()
@discussion attempts to write out the config file
if it can't write it out it will prompt the
user to download the config file.
*/
function install_create_config($web_path,$username,$password,$hostname,$database) {
/*
First Test The Variables they've given us to make
sure that they actually work!
*/
// Connect to the DB
if(!$dbh = @mysql_pconnect($hostname,$username,$password)) {
return false;
}
if (!$db_selected = @mysql_select_db($database, $dbh)) {
return false;
}
/* Read in the .dist file and spit out the .cfg */
$dist_handle = @fopen("config/ampache.cfg.php.dist",'r');
$dist_data = @fread($dist_handle,filesize("config/ampache.cfg.php.dist"));
fclose($dist_handle);
$dist_array = explode("\n",$dist_data);
// Rather then write it out right away, let's build the string
// incase we can't write to the FS and have to make it a download
foreach ($dist_array as $row) {
if (preg_match("/^#?web_path\s*=/",$row)) {
$row = "web_path = \"$web_path\"";
}
elseif (preg_match("/^#?local_db\s*=/",$row)) {
$row = "local_db = \"$database\"";
}
elseif (preg_match("/^#?local_host\s*=/",$row)) {
$row = "local_host = \"$hostname\"";
}
elseif (preg_match("/^#?local_username\s*=/",$row)) {
$row = "local_username = \"$username\"";
}
elseif (preg_match("/^#?local_pass\s*=/",$row)) {
$row = "local_pass = \"$password\"";
}
$config_data .= $row . "\n";
} // foreach row in config file
/* Attempt to Write out File */
if (!$config_handle = @fopen("config/ampache.cfg.php",'w')) {
$browser = new Browser();
$browser->downloadHeaders("ampache.cfg.php","text/plain",false,filesize("config/ampache.cfg.php.dist"));
echo $config_data;
exit();
}
if (!@fwrite($config_handle,$config_data)) {
return false;
}
return true;
} // install_create_config
/*!
@function install_create_account
@discussion this creates your initial account
*/
function install_create_account($username,$password) {
$results = read_config($GLOBALS['configfile'], 0, 0);
$dbh = check_database($results['libglue']['local_host'],$results['libglue']['local_username'],$results['libglue']['local_pass'],$results['libglue']['local_db']);
@mysql_select_db($results['libglue']['local_db'],$dbh);
$username = sql_escape($username,$dbh);
$password = sql_escape($password,$dbh);
$sql = "INSERT INTO user (`username`,`password`,`offset_limit`,`access`) VALUES ('$username',PASSWORD('$password'),'50','admin')";
$db_results = mysql_query($sql, $dbh);
$insert_id = mysql_insert_id($dbh);
if (!$insert_id) { return false; }
return true;
} // install_create_account
?>

77
lib/log.php Normal file
View file

@ -0,0 +1,77 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@function log_event
@discussion logs an event either to a database
or to a defined log file based on config options
*/
function log_event($username='Unknown',$event_name,$event_description,$log_name='ampache') {
/* Set it up here to make sure it's _always_ the same */
$log_time = time();
set_time_limit(0);
$log_filename = conf('log_path') . "/$log_name." . date("Ymd",$log_time) . ".log";
$log_line = date("Y-m-d H:i:s",$log_time) . " { $username } ( $event_name ) - $event_description \n";
error_log($log_line, 3, $log_filename) or die("Error: Unable to write to log ($log_filename)");
} // log_event
/*!
@function ampache_error_handler
@discussion an error handler for ampache that traps
as many errors as it can and logs em
*/
function ampache_error_handler($errno, $errstr, $errfile, $errline) {
switch ($errno) {
case '2':
case '128':
case '8':
case '32':
return true;
break;
case '1':
$error_name = "Fatal run-time Error";
break;
case '4':
$error_name = "Parse Error";
break;
case '16':
$error_name = "Fatal Core Error";
break;
case '64':
$error_name = "Zend run-time Error";
break;
default:
$error_name = "Error";
break;
} // end switch
$log_line = "[$errstr] $error_name on line $errline in $errfile";
log_event($_SESSION['userdata']['username'],'error',$log_line,'ampache-error');
} // ampache_error_handler
?>

75
lib/mpd.php Normal file
View file

@ -0,0 +1,75 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@function addToPlaylist()
@discussion adds a bunch of songs to the mpd playlist
this takes a mpd object, and an array of songs
*/
function addToPlaylist( $myMpd, $song_ids=array()) {
foreach( $song_ids as $song_id ) {
/* There are two ways to do this, filename or URL */
if (conf('mpd_method') == 'url') {
// We just need to generate a standard stream URL and pass that
$song = new Song($song_id);
$sess_id = session_id();
if ($song->type == ".flac") { $song->type = ".ogg"; }
if ($GLOBALS['user']->prefs['play_type'] == 'downsample') {
$ds = $GLOBALS['user']->prefs['sample_rate'];
}
$song_url = conf('web_path') . "/play/index.php?song=$song_id&uid=" . $GLOBALS['user']->id . "&sid=$sess_id&ds=$ds&name=." . $song->type;
if (is_null( $myMpd->PlAdd($song_url) ) ) {
$log_line = _("Error") . ": " . _("Could not add") . ": " . $song_url . " : " . $myMpd->errStr;
echo "<font class=\"error\">$log_line</font><br />\n";
log_event($GLOBALS['user']->username,'add',$log_line);
} // if it's null
} // if we want urls
else {
$song = new Song( $song_id );
$song_filename = $song->get_rel_path();
if( is_null( $myMpd->PLAdd( $song_filename ) ) ) {
$log_line = _("Error") . ": " . _("Could not add") . ": " . $song_filename . " : " . $myMpd->errStr;
echo "<font class=\"error\">$log_line</font><br />\n";
log_event($_SESSION['userdata']['username'],'add',$log_line);
} // end if it's null
// We still need to count if they use the file method
else {
$GLOBALS['user']->update_stats( $song_id );
} // end else
} // end else not url method
} // end foreach
} // addToPlaylist
/*!
@function show_mpd_control
@discussion shows the mpd controls
*/
function show_mpd_control() {
$_REQUEST['action'] = 'show_control';
require_once ('amp-mpd.php');
} // show_mpd_control
?>

237
lib/perl/Local/Ampache/Ampache.pm Executable file
View file

@ -0,0 +1,237 @@
#!/usr/bin/perl -w
# Find and file away MP3's. Run multiple times and will
# ignore addition of duplicates in db (based on MD5 hash
# of full file path.
package Local::Ampache;
#use File::Find;
use DBI;
#use strict;
use Data::Dumper;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %ampache);
require Exporter;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw(
);
my $TRUE = 1;
my $FALSE = 0;
$VERSION = '';
my %ampache = ();
sub new {
my ($class, $path) = @_;
open(CONFIG, "< $path/config/ampache.cfg")
or die "Could not find $path/config/ampache.cfg. Is it readable by me?\n";
my %config = ();
while (<CONFIG>) {
next if ($_ =~ /^#.*/);
if ( $_ =~ /(.*?)\s+=\s+(.*)/ ) {
$config{$1} = $2;
}
}
my $name = $config{'local_db'};
my $self =
{
_name => $config{'local_db'},
_database => $config{'local_db'},
_sth_cache => {},
_connect => {
dbd => 'mysql',
host => $config{'local_host'},
port => '3306',
username => $config{'local_username'},
password => $config{'local_pass'}
},
_dbh => '',
_path => $path,
_config => \%config,
_debug => $FALSE
};
$VERSION = $config{'VERSION'};
$Local::Ampache::ampache{$name} = bless ($self, $class);
$self->{_dbh} = $self->dbh( $name );
return $self;
} # End New Ampache Module
sub DESTROY {
my ($self) = @_;
foreach my $sth (values %{$self->{_sth_cache}}) {
if (defined($sth)) { $sth->finish(); }
}
if (defined($self->{_dbh}) and $self->{_dbh} ne "") {
$self->{_dbh}->disconnect();
}
}
sub get
{
my ($class, $name) = @_;
if (not $Local::Ampache::ampache{$name}) {
$Local::Ampache::ampache{$name} = Local::Ampache->new($name);
}
return bless $Local::Ampache::ampache{$name}, $class;
}
sub dbh
{
my ($self, $database) = @_;
my $dbh = '';
if($self->{_dbh} )
{
return $self->{_dbh};
}
else
{
my $connect_string = [ sprintf("dbi:%s:database=%s;host=%s;port=%s",
$self->{_connect}{dbd},
$self->{_database},
$self->{_connect}{host},
$self->{_connect}{port}),
$self->{_connect}{username},
$self->{_connect}{password} ];
$dbh = DBI->connect( @{$connect_string},
{PrintError => 0,
RaiseError => 0,
AutoCommit => 1});
if ( !$dbh )
{
die "Failed to connect to database. Exiting.";
}
}
return $dbh;
}
sub prepare_sth_cache {
my ($self, $sql) = @_;
# the call to dbh() forces a connection if one has dropped
my $dbh = $self->dbh();
return $dbh->prepare($sql);
}
sub get_table_where
{
my ($self, $name, $where,$select) = @_;
if (!$select) { $select = "*"; }
my ($sql, $sth);
my $dbh = $self->dbh();
$sql = qq{SELECT $select FROM $name $where};
$sth = $dbh->prepare($sql);
$sth->execute();
my @table = ();
while ( my $ary = $sth->fetchrow_hashref() )
{
push(@table, $ary);
}
return (@table);
}
sub get_catalog_option
{
my ($self, $catalog, $field) = @_;
if(!$self->{_catalog}{$catalog}) {
print "Loading catalog settings\n";
my ($sql, $sth);
$sql = qq{SELECT * FROM catalog WHERE path = '$catalog'};
my $dbh = $self->dbh();
$sth = $dbh->prepare($sql);
$sth->execute();
$self->{_catalog}{$catalog} = $sth->fetchrow_hashref();
}
return $self->{_catalog}->{$catalog}->{$field};
}
sub change_flags
{
my ($self, $song, $oldflag, $newflag) = @_;
my ($sql, $sth);
my $dbh = $self->dbh();
$sql = "UPDATE flagged SET type = '$newflag' WHERE song = '".$song->{'id'}."' AND type = '$oldflag'";
$sth = $dbh->prepare($sql);
$sth->execute();
}
sub update_song
{
my ($self, $filename, $song) = @_;
my ($sql, $sth);
my $dbh = $self->dbh();
$filename =~ s/'/\\'/g;
$filename =~ s/"/\\"/g;
$filename =~ s/\Q%\E//g;
$sql = "UPDATE song SET file = '$filename' WHERE id = '".$song->{'id'}."'";
$sth = $dbh->prepare($sql);
$sth->execute();
}
sub get_song_info
{
my ($self, $song) = @_;
my ($sql, $sth);
my $dbh = $self->dbh();
if ( not $self->{_sth_cache}{get_song_info})
{
$self->{_sth_cache}{get_song_info} = $self->prepare_sth_cache(
qq{SELECT catalog.path AS catalog,song.file,song.id,song.title,song.track,song.year,song.comment,album.name AS album, artist.name AS artist,genre FROM song,album,artist,catalog WHERE song.id = ? AND album.id = song.album AND artist.id = song.artist AND song.catalog = catalog.id});
}
$sth = $self->{_sth_cache}{get_song_info};
$sth->execute($song);
my @table = ();
while ( my $ary = $sth->fetchrow_hashref() )
{
push(@table, $ary);
}
return (@table);
}
#sub get_song_info
#{
# my ($self, $song) = @_;
#
# my ($sql, $sth);
# my $dbh = $self->dbh();
# if ( not $self->{_sth_cache}{song_info}{$song} )
# {
# $sql = qq{SELECT * FROM song WHERE id = $song};
# $sth = $dbh->prepare($sql);
# $self->{_sth_cache}{song_info}{$song} = $sth;
# }
#
# $sth = $self->{_sth_cache}{song_info}{$song};
# $sth->execute();
#
# my @song_info = $sth->fetchrow_hashref();
# return (@song_info);
#}
1;
__END__

View file

@ -0,0 +1,7 @@
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'Local::Ampache',
'VERSION_FROM' => 'Ampache.pm', # finds $VERSION
);

281
lib/preferences.php Normal file
View file

@ -0,0 +1,281 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Preferences Library
@discussion This contains all of the functions needed for the preferences
*/
/*!
@function get_site_preferences
@discussion gets all of the preferences for this Ampache site
*/
function get_site_preferences() {
$results = array();
$sql = "SELECT preferences.name, preferences.type, user_preference.value, preferences.description FROM preferences,user_preference " .
" WHERE preferences.id=user_preference.preference AND user_preference.user = '0' ORDER BY `type`,`name`";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_object($db_results)) {
$results[] = $r;
}
return $results;
} // get_site_preferences
/*!
@function set_site_preferences
@discussion sets the conf() function with the current site preferences from the db
*/
function set_site_preferences() {
$results = array();
$sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user='0' AND user_preference.preference=preferences.id";
$db_results = @mysql_query($sql, dbh());
while ($r = @mysql_fetch_object($db_results)) {
$results[$r->name] = $r->value;
} // db results
if (strlen($results['theme_name']) > 0) {
$results['theme_path'] = "/themes/" . $results['theme_name'];
}
conf($results,1);
} // set_site_preferences
/*!
@function clean_preference_name
@discussion s/_/ /g & upper case first
*/
function clean_preference_name($name) {
$name = str_replace("_"," ",$name);
$name = ucwords($name);
return $name;
} // clean_preference_name
/*!
@function update_preferences
@discussion grabs the current keys that should be added
and then runs throught $_REQUEST looking for those
values and updates them for this user
*/
function update_preferences($pref_id=0) {
$pref_user = new User(0,$pref_id);
/* Get current keys */
$sql = "SELECT id,name,type FROM preferences";
if ($pref_id != '0') { $sql .= " WHERE type='user'"; }
$db_results = mysql_query($sql, dbh());
// Collect the current possible keys
while ($r = mysql_fetch_object($db_results)) {
$results[] = array('id' => $r->id, 'name' => $r->name,'type' => $r->type);
}
foreach ($results as $data) {
/* Get the Value from POST/GET var called $data */
//FIXME: Do this right....
$type = $data['type'];
$name = $data['name'];
$apply_to_all = "check_" . $data['name'];
$id = $data['id'];
$value = sql_escape(scrub_in($_REQUEST[$name]));
if (has_preference_access($name) AND isset($_REQUEST[$name])) {
$sql = "UPDATE user_preference SET `value`='$value' WHERE preference='$id' AND user='$pref_id'";
$db_results = mysql_query($sql, dbh());
/* Check to see if this is a theme, and if so run the theme updater */
if ($name == "theme_name" AND $pref_user->prefs['theme_name'] != $_REQUEST[$name]) {
set_theme_colors($value,$pref_id);
} // run theme updater
} // if access
if ($GLOBALS['user']->has_access(100) AND $_REQUEST[$apply_to_all] =='1') {
$sql = "UPDATE user_preference SET `value`='$value' WHERE preference='$id'";
$db_results = mysql_query($sql, dbh());
}
} // end foreach preferences
} // update_preferences
/*!
@function has_preference_access
@discussion makes sure that the user has sufficient
rights to actually set this preference, handle
as allow all, deny X
//FIXME:
// This is no longer needed, we just need to check against preferences.level
*/
function has_preference_access($name) {
global $user;
if (conf('demo_mode')) {
return false;
}
switch($name) {
case 'download':
case 'upload':
case 'quarantine':
case 'upload_dir':
case 'sample_rate':
case 'direct_link':
$level = 100;
break;
default:
$level = 1;
break;
} // end switch key
if ($user->has_access($level)) {
return true;
}
return false;
} // has_preference_access
/*!
@function create_preference_input
@discussion takes the key and then creates
the correct type of input for updating it
*/
function create_preference_input($name,$value) {
$len = strlen($value);
if ($len <= 1) { $len = 8; }
if (!has_preference_access($name)) {
if ($value == '1') {
echo "Enabled";
}
elseif ($value == '0') {
echo "Disabled";
}
else {
echo $value;
}
return;
} // if we don't have access to it
switch($name) {
case 'download':
case 'quarantine':
case 'upload':
case 'access_list':
case 'lock_songs':
case 'xml_rpc':
case 'force_http_play':
case 'no_symlinks':
case 'use_auth':
case 'access_control':
case 'demo_mode':
case 'direct_link':
if ($value == '1') { $is_true = "selected=\"selected\""; }
else { $is_false = "selected=\"selected\""; }
echo "<select name=\"$name\">\n";
echo "\t<option value=\"1\" $is_true>" . _("Enable") . "</option>\n";
echo "\t<option value=\"0\" $is_false>" . _("Disable") . "</option>\n";
echo "</select>\n";
break;
case 'play_type':
if ($value == 'local_play') { $is_local = "selected=\"selected\""; }
elseif ($value == 'icecast2') { $is_ice = "selected=\"selected\""; }
elseif ($value == 'downsample') { $is_down = "selected=\"selected\""; }
elseif ($value == 'mpd') { $is_mpd = "selected=\"selected\""; }
elseif ($value == 'slim') { $is_slim = "selected=\"selected\""; }
else { $is_stream = "selected=\"selected\""; }
echo "<select name=\"$name\">\n";
if (conf('allow_local_playback')) {
echo "\t<option value=\"local_play\" $is_local>" . _("Local") . "</option>\n";
}
if (conf('allow_stream_playback')) {
echo "\t<option value=\"stream\" $is_stream>" . _("Stream") . "</option>\n";
}
if (conf('allow_icecast_playback')) {
echo "\t<option value=\"icecast2\" $is_ice>" . _("IceCast") . "</option>\n";
}
if (conf('allow_downsample_playback')) {
echo "\t<option value=\"downsample\" $is_down>" . _("Downsample") . "</option>\n";
}
if (conf('allow_mpd_playback')) {
echo "\t<option value=\"mpd\" $is_mpd>" . _("Music Player Daemon") . "</option>\n";
}
if (conf('allow_slim_playback')) {
echo "\t<option value=\"slim\" $is_slim>" . _("SlimServer") . "</option>\n";
}
echo "</select>\n";
break;
case 'playlist_type':
$var_name = $value . "_type";
${$var_name} = "selected=\"selected\"";
echo "<select name=\"$name\">\n";
echo "\t<option value=\"m3u\" $m3u_type>" . _("M3U") . "</option>\n";
echo "\t<option value=\"simple_m3u\" $simple_m3u_type>" . _("Simple M3U") . "</option>\n";
echo "\t<option value=\"pls\" $pls_type>" . _("PLS") . "</option>\n";
echo "\t<option value=\"asx\" $asx_type>" . _("Asx") . "</option>\n";
echo "</select>\n";
break;
case 'lang':
$var_name = $value . "_lang";
${$var_name} = "selected=\"selected\"";
echo "<select name=\"$name\">\n";
echo "\t<option value=\"en_US\" $en_US_lang>" . _("English") . "</option>\n";
echo "\t<option value=\"de_DE\" $de_DE_lang>" . _("German") . "</option>\n";
echo "\t<option value=\"fr_FR\" $fr_FR_lang>" . _("French") . "</option>\n";
echo "\t<option value=\"tr_TR\" $tr_TR_lang>" . _("Turkish") . "</option>\n";
echo "</select>\n";
break;
case 'theme_name':
$themes = get_themes();
echo "<select name=\"$name\">\n";
foreach ($themes as $theme) {
$is_selected = "";
if ($value == $theme['path']) { $is_selected = "selected=\"selected\""; }
echo "\t<option value=\"" . $theme['path'] . "\" $is_selected>" . $theme['name'] . "</option>\n";
} // foreach themes
echo "</select>\n";
break;
default:
echo "<input type=\"text\" size=\"$len\" name=\"$name\" value=\"$value\" />";
break;
}
} // create_preference_input
?>

64
lib/rss.php Normal file
View file

@ -0,0 +1,64 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@function show_now_playingRSS
@discussion creates a RSS fead for the now
playing information
*/
function show_now_playingRSS () {
$dbh = dbh();
$web_path = conf('web_path');
$rss_main_title = conf('rss_main_title');
$rss_main_description = conf('rss_main_description');
$rss_main_copyright = conf('rss_main_copyright');
$rss_main_language = conf('rss_main_language');
$rss_song_description = conf('rss_song_description');
$sql = "SELECT * FROM now_playing ORDER BY start_time DESC";
$db_result = mysql_query($sql, $dbh);
$today = date("d-m-Y");
echo "<rss version=\"0.91\">";
echo "<channel>\n<title>$rss_main_title</title>\n";
echo "<link>$web_path</link>\n<description>$rss_main_description</description>\n";
echo "<copyright>$rss_main_copyright</copyright>";
echo "<pubDate>$today</pubDate>\n<language>$rss_main_language</language>\n";
while ($r = mysql_fetch_object($db_result)) {
$song = new Song($r->song_id);
$song->format_song();
$user = get_user_byid($r->user_id);
if (is_object($song)) {
$artist = $song->f_artist;
$album = $song->get_album_name();
$text = "$artist - $song->f_title";
echo "<item> ";
echo " <title><![CDATA[$text]]></title> ";
echo " <link>$web_path/albums.php?action=show&amp;album=$song->album</link>";
echo " <description>$rss_song_description</description>";
echo " <pubDate>$today</pubDate>";
echo "</item>";
}
}
echo "</channel>\n</rss>";
} // show_now_playingRSS
?>

185
lib/search.php Normal file
View file

@ -0,0 +1,185 @@
<?php
/*
Copyright (c) 2004 ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
This library handles all the searching!
*/
/*!
@function run_search
@discussion run a search, takes string,field,type and returns an array
of results of the correct type (song, album, artist)
*/
function run_search($string,$field,$type) {
// Clear this so it doesn't try any fanzy view mojo on us
unset($_SESSION['view_script']);
// Escape input string
$string = sql_escape($string);
// Switch on the field --> type and setup sql statement
switch ($field === 0 ? '': $field) {
case 'artist':
if ($type === 'fuzzy') {
$sql = "SELECT id FROM artist WHERE name LIKE '%$string%'";
}
else {
$sql = "SELECT id FROM artist WHERE name ='$string'";
}
$artists = get_artists($sql, 'format');
if ($artists) {
show_artists($artists);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'album':
if ($type === 'fuzzy') {
$sql = "SELECT id FROM album WHERE name LIKE '%$string%'";
}
else {
$sql = "SELECT id FROM album WHERE name='$string'";
}
$albums = get_albums($sql);
if (count($albums)) {
show_albums($albums);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_title':
if ($type === 'fuzzy') {
$sql = "SELECT id FROM song WHERE title LIKE '%$string%'";
}
else {
$sql = "SELECT id FROM song WHERE title = '$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_genre':
if ($type === 'fuzzy') {
$sql = "SELECT song.id FROM song,genre WHERE song.genre=genre.id AND genre.name LIKE '%$string%'";
}
else {
$sql = "SELECT song.id FROM song,genre WHERE song.genre=genre.id AND genre.name='$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_year':
if ($type === 'fuzzy') {
$sql = "SELECT song.id FROM song WHERE song.year LIKE '%$string%'";
}
else {
$sql = "SELECT song.id FROM song WHERE song.year='$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_length':
case 'song_bitrate':
if ($type === 'fuzzy') {
$sql = "SELECT song.id FROM song WHERE song.bitrate LIKE '%$string%'";
}
else {
$sql = "SELECT song.id FROM song WHERE song.bitrate='$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_min_bitrate':
$string = $string * 1000;
$sql = "SELECT song.id FROM song WHERE song.bitrate >= '$string'";
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_comment':
if ($type === 'fuzzy') {
$sql = "SELECT song.id FROM song WHERE song.comment LIKE '%$string%'";
}
else {
$sql = "SELECT song.id FROM song WHERE song.comment='$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
case 'song_filename':
if ($type === 'fuzzy') {
$sql = "SELECT song.id FROM song WHERE song.file LIKE '%$string%'";
}
else {
$sql = "SELECT song.id FROM song WHERE song.file='$string'";
}
$song_ids = get_songs($sql, 'format');
if ($song_ids) {
show_songs($song_ids);
}
else {
echo "<div class=\"error\" align=\"center\">" . _("No Results Found") . "</div>";
}
break;
} // end switch
} // run_search
?>

57
lib/song.php Normal file
View file

@ -0,0 +1,57 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
@header Song Library
@discussion This library handles song related functions.... woohoo!
This library is defunt, please try use the song class if possible
*/
/*!
@function get_songs
@discussion pass a sql statement, and it gets full song info and returns
an array of the goods.. can be set to format them as well
*/
function get_songs($sql, $action=0) {
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_array($db_results)) {
// $song_info = get_songinfo($r['id']);
// if ($action === 'format') { $song = format_song($song_info); }
// else { $song = $song_info; }
$results[] = $r['id'];
}
return $results;
} // get_albums
/*!
@function format_song
@discussion takes a song array and makes it html friendly
*/
function format_song($song) {
return $song;
} // format_song
?>

124
lib/themes.php Normal file
View file

@ -0,0 +1,124 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All Rights Reserved
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@function get_themes()
@discussion this looks in /themes and pulls all of the
theme.cfg.php files it can find and returns an
array of the results
*/
function get_themes() {
/* Open the themes dir and start reading it */
$handle = @opendir(conf('prefix') . "/themes");
if (!is_resource($handle)) {
if (conf('debug')) { log_event($_SESSION['userdata']['username'],'theme',"Error unable to open Themes Directory"); }
}
$results = array();
while ($file = readdir($handle)) {
$full_file = conf('prefix') . "/themes/" . $file;
/* See if it's a directory */
if (is_dir($full_file) AND substr($file,0,1) != ".") {
$config_file = $full_file . "/theme.cfg.php";
/* Open the theme.cfg.php file */
$r = read_config($config_file);
$r['path'] = $file;
$results[] = $r;
}
} // end while directory
return $results;
} // get_themes
/*!
@function get_theme
@discussion get a single theme and read the config file
then return the results
*/
function get_theme($name) {
$config_file = conf('prefix') . "/themes/" . $name . "/theme.cfg.php";
$results = read_config($config_file);
$results['path'] = $name;
return $results;
} // get_theme
/*!
@function set_theme
@discussion Resets all of the colors for this theme
*/
function set_theme_colors($theme_name,$user_id) {
/* We assume if we've made it this far we've got the right to do it
This could be dangerous but eah!
*/
$theme = get_theme($theme_name);
if (!count($theme['color'])) { return false; }
foreach ($theme['color'] as $key=>$color) {
$sql = "SELECT id FROM preferences WHERE name='" . sql_escape($key) . "'";
$db_results = mysql_query($sql, dbh());
$results = mysql_fetch_array($db_results);
$sql = "UPDATE user_preference SET `value`='" . sql_escape($color) . "' WHERE `user`='" . $user_id . "' AND " .
" preference='" . $results[0] . "'";
$db_results = mysql_query($sql, dbh());
} // theme colors
} // set_theme_colors
/*!
@function set_theme
@discussion this sets the needed vars for the theme
*/
function set_theme() {
if (strlen(conf('theme_name')) > 0) {
$theme_path = "/themes/" . conf('theme_name');
conf(array('theme_path'=>$theme_path),1);
}
} // set_theme
/*!
@function get_theme_author
@discussion returns the author of this theme
*/
function get_theme_author($theme_name) {
$theme_path = conf('prefix') . "/themes/" . conf('theme_name') . "/theme.cfg.php";
$results = read_config($theme_path);
return $results['author'];
} // get_theme_author
?>

437
lib/ui.php Normal file
View file

@ -0,0 +1,437 @@
<?php
/*
Copyright (c) 2001 - 2005 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header UI Function Library
This contains functions that are generic, and display information
things like a confirmation box, etc and so forth
*/
/*!
@function show_confirmation
@discussion shows a confirmation of an action
@param $next_url Where to go next
@param $title The Title of the message
@param $text The details of the message
*/
function show_confirmation($title,$text,$next_url) {
if (substr_count($next_url,conf('web_path'))) {
$path = $next_url;
}
else {
$path = conf('web_path') . "/$next_url";
}
require (conf('prefix') . "/templates/show_confirmation.inc.php");
} // show_confirmation
/*!
@function set_preferences
@discussion legacy function...
//FIXME: Remove References
*/
function set_preferences() {
get_preferences();
return true;
} // set_preferences
/*!
@function get_preferences
@discussion reads this users preferences
*/
function get_preferences($username=0) {
/* Get System Preferences first */
$sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user_preference.user='0' " .
" AND user_preference.preference = preferences.id AND preferences.type='system'";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_object($db_results)) {
$results[$r->name] = $r->value;
} // end while sys prefs
conf($results, 1);
unset($results);
if (!$username) { $username = $_SESSION['userdata']['username']; }
$user = new User($username);
$sql = "SELECT preferences.name,user_preference.value FROM preferences,user_preference WHERE user_preference.user='$user->id'" .
" AND user_preference.preference=preferences.id";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_object($db_results)) {
$results[$r->name] = $r->value;
}
unset($results['user'], $results['id']);
conf($results, 1);
} // get_preferences
/*!
@function flip_class
@discussion takes an array of 2 class names
and flips them back and forth and
then echo's out [0]
*/
function flip_class($array=0) {
static $classes = array();
if ($array) {
$classes = $array;
}
else {
$classes = array_reverse($classes);
return $classes[0];
}
} // flip_class
/*!
@function clear_now_playing
@discussion Clears the now playing information incase something has
gotten stuck in there
*/
function clear_now_playing() {
$sql = "DELETE FROM now_playing";
$db_results = mysql_query($sql, dbh());
return true;
} // clear_now_playing
/*!
@function show_tool_box
@discussion shows the toolbox
*/
function show_tool_box ($title, $items) {
include(conf('prefix') . "/templates/tool_box.inc");
}// show_tool_box
/*!
@function show_box
@discussion shows a generic box
*/
function show_box($title,$items) {
include(conf('prefix') . "/templates/show_box.inc");
} // show_box
/*!
@function show_menu_items
@discussion shows menu items
*/
function show_menu_items ($high) {
include(conf('prefix') . "/templates/menu.inc");
} // show_menu_items
/*!
@function _
@discussion checks to see if the alias _ is defined
if it isn't it defines it as a simple return
*/
if (!function_exists('_')) {
function _($string) {
return $string;
} // _
} // if _ isn't defined
/*!
@function show_playlist_menu
@discussion playlist functions
*/
function show_playlist_menu () {
echo "<br /><span class=\"header2\">" . _("Playlist Actions") . ": <a href=\"" . conf('web_path') . "/playlist.php?action=new\">" . _("New") ."</a> | ";
echo "<a href=\"" . conf('web_path') . "/playlist.php\"> " . _("View All") . "</a> | ";
echo "<a href=\"" . conf('web_path') . "/playlist.php?action=show_import_playlist\"> " . _("Import") . "</a>";
echo "</span><br /><br />";
} // show_playlist_menu
/*!
@function show_admin_menu
@discussion shows the admin menu
*/
function show_admin_menu ($admin_highlight) {
include(conf('prefix') . "/templates/admin_menu.inc");
} // show_admin_menu
/*!
@function access_denied
@discussion throws an error if they try to do something
that they aren't allowed to
*/
function access_denied() {
show_template('style');
show_footer();
echo "<br /><br /><br />";
echo "<div class=\"fatalerror\">Error Access Denied</div>\n";
show_footer();
exit();
} // access_denied
/*!
@function show_users
@discussion shows all users (admin function)
*/
function show_users () {
$dbh = dbh();
// Setup the View Ojbect
$view = new View();
$view->import_session_view();
// if we are returning
if ($_REQUEST['keep_view']) {
$view->initialize();
}
// If we aren't keeping the view then initlize it
else {
$sql = "SELECT username FROM user";
$db_results = mysql_query($sql, $dbh);
$total_items = mysql_num_rows($db_results);
if ($match != "Show_all") { $offset_limit = $_SESSION['userdata']['offset_limit']; }
$view = new View($sql, 'admin/users.php','fullname',$total_items,$offset_limit);
}
$db_result = mysql_query($view->sql, $dbh);
require(conf('prefix') . "/templates/show_users.inc");
} // show_users()
/*!
@function return_referer
@discussion returns the script part of the
referer address passed by the web browser
this is not %100 accurate
*/
function return_referer() {
$web_path = substr(conf('web_path'),0,strlen(conf('web_path'))-1-strlen($_SERVER['SERVER_PORT'])) . "/";
$next = str_replace($web_path,"",$_SERVER['HTTP_REFERER']);
// If there is more than one :// we know it's fudged
// and just return the index
if (substr_count($next,"://") > 1) {
return "index.php";
}
return $next;
} // return_referer
/*!
@function show_alphabet_list
@discussion shows the A-Z,0-9 lists for
albums and artist pages
*/
function show_alphabet_list ($type,$script="artist.php",$selected="false") {
$list = array(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,1,2,3,4,5,6,7,8,9,"0");
$style_name = "style_" . strtolower($selected);
${$style_name} = "style=\"font-weight:bold;\"";
echo "<div class=\"alphabet\">";
foreach ($list as $l) {
$style_name = "style_" . strtolower($l);
echo "<a href=\"". conf('web_path') ."/$script?action=match&amp;match=$l\" " . ${$style_name} . ">$l</a> | \n";
}
echo " <a href=\"". conf('web_path') ."/$script?action=match&amp;match=Browse\" $style_browse>" . _("Browse") . "</a> | \n";
if ($script == "albums.php") {
echo " <a href=\"". conf('web_path') ."/$script?action=match&amp;match=Show_missing_art\" $style_show_missing_art>" . _("Show w/o art") . "</a> | \n";
} // if we are on the albums page
echo " <a href=\"". conf('web_path') ."/$script?action=match&amp;match=Show_all\" $style_show_all>" . _("Show all") . "</a>";
echo "</div>\n";
} // show_alphabet_list
/*!
@function show_local_control
@discussion shows the controls
for localplay
*/
function show_local_control () {
require_once(conf('prefix') . "/templates/show_localplay.inc");
} // show_local_control
/*!
@function truncate_with_ellipse
@discussion truncates a text file to specified length by adding
thre dots (ellipse) to the end
(Thx Nedko Arnaudov)
*/
function truncate_with_ellipse($text, $max=27) {
/* If we want it to be shorter than three, just throw it back */
if ($max > 3) {
/* Make sure the functions exist before doing the iconv mojo */
if (function_exists('iconv') && function_exists('iconv_substr') && function_exists('iconv_strlen')) {
if (iconv_strlen($text, conf('site_charset')) > $max) {
$text = iconv_substr($text, 0, $max-3, conf('site_charset'));
$text .= iconv("ISO-8859-1", conf('site_charset'), "...");
}
}
/* Do normal substr if we don't have iconv */
else {
if (strlen($text) > $max) {
$text = substr($text,0,$max-3)."...";
}
} // else no iconv
} // else greater than 3
return $text;
} // truncate_with_ellipse
/*!
@function show_footer
@discussion shows the footer of the page
*/
function show_footer() {
$class = "table-header";
echo "<br /><br /><br /><div class=\"$class\" style=\"border: solid thin black;\">&nbsp</div>";
} // show_footer
/*!
@function show_now_playing
@discussion shows the now playing template
*/
function show_now_playing() {
$dbh = dbh();
$web_path = conf('web_path');
$results = get_now_playing();
require (conf('prefix') . "/templates/show_now_playing.inc");
} // show_now_playing
/*!
@function show_user_registration
@discussion this function is called for a new user
registration
@author Terry
*/
//function show_user_registration ($id, $username, $fullname, $email, $access, $type, $error) {
//FIXME: See above
function show_user_registration ($values=array()) {
require (conf('prefix') . "/templates/show_user_registration.inc.php");
} // show_user_registration
/*!
@function show_edit_profile
@discussion shows a single user profile for editing
*/
function show_edit_profile($username) {
$this_user = new User($username);
require (conf('prefix') . "/templates/show_user.inc.php");
} // show_edit_profile
/*!
@function show_playlist
@discussion this shows the current playlist
*/
function show_playlist($playlist_id) {
/* Create the Playlist */
$playlist = new Playlist($playlist_id);
$song_ids = $playlist->get_songs();
if (count($song_ids) > 0) {
show_songs($song_ids, $playlist->id);
}
else {
echo "<p>" . _("No songs in this playlist.") . "</p>\n";
}
} // show_playlist
/*!
@function show_play_selected
@discussion this shows the playselected/add to playlist
box, which includes a little javascript
*/
function show_play_selected() {
require (conf('prefix') . "/templates/show_play_selected.inc.php");
} // show_play_selected
/*!
@function get_now_playing
@discussion gets the now playing information
*/
function get_now_playing() {
$sql = "SELECT song_id,user_id FROM now_playing ORDER BY start_time DESC";
$db_results = mysql_query($sql, dbh());
while ($r = mysql_fetch_assoc($db_results)) {
$song = new Song($r['song_id']);
$song->format_song();
$np_user = new User(0,$r['user_id']);
$results[] = array('song'=>$song,'user'=>$np_user);
} // end while
return $results;
} // get_now_playing
/*!
@function show_clear
@discussion this is a hack because of the float mojo
*/
function show_clear() {
echo "\n<div style=\"clear:both;\">&nbsp;</div>\n";
} // show_clear
?>

143
lib/xmlrpc.php Normal file
View file

@ -0,0 +1,143 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header XML-RPC Library
@discussion If you want an honest answer NFC. Copy and paste baby!
*/
/*!
@function remote_server_query
@discussion don't ask don't tell
*/
function remote_server_query($m) {
$result = array();
// we only want to send the local entries
$sql = "SELECT name FROM catalog WHERE catalog_type='local'";
$db_result = mysql_query($sql, dbh());
while ( $i = mysql_fetch_row($db_result) ) {
$result[] = $i;
}
set_time_limit(0);
$encoded_array = new xmlrpcval($result);
log_event($_SESSION['userdata']['username'],'xml-rpc_encoded',$encoded_array);
return new xmlrpcresp($encoded_array);
return $result;
} // remote_server_query
/*!
@function remote_song_query
@discussion return all local songs and their
information
*/
function remote_song_query() {
//FIXME: We should add catalog level access control
// Get me a list of all local catalogs
$sql = "SELECT catalog.id FROM catalog WHERE catalog_type='local'";
$db_results = mysql_query($sql, dbh());
$results = array();
//FIXME: enabled --> smallint(1) T/F boolean mojo
$sql = "SELECT song.id FROM song WHERE song.status='enabled' AND";
// Get the catalogs and build the query!
while ($r = mysql_fetch_object($db_results)) {
if (preg_match("/catalog/",$sql)) {
$sql .= " OR song.catalog='$r->id'";
}
else {
$sql .= " song.catalog='$r->id'";
}
} // build query
$db_results = mysql_query($sql, dbh());
// Recurse through the songs and build a results
// array that is base64_encoded
while ($r = mysql_fetch_object($db_results)) {
$song = new Song($r->id);
$song->album = $song->get_album_name();
$song->artist = $song->get_artist_name();
$song->genre = $song->get_genre_name();
// Format the output
$output = '';
$output = $song->artist . "::" . $song->album . "::" . $song->title . "::" . $song->comment .
"::" . $song->year . "::" . $song->bitrate . "::" . $song->rate . "::" . $song->mode .
"::" . $song->size . "::" . $song->time . "::" . $song->track . "::" . $song->genre . "::" . $r->id;
$output = base64_encode($output);
$results[] = $output;
// Prevent Timeout
set_time_limit(0);
} // while songs
set_time_limit(0);
$encoded_array = old_xmlrpc_encode($results);
return new xmlrpcresp($encoded_array);
} // remote_song_query
/*!
@function remote_server_denied
@discussion Access Denied Sucka!
*/
function remote_server_denied() {
$result = array();
$result['access_denied'] = "Access Denied: Sorry, but " . $_SERVER['REMOTE_ADDR'] . " does not have access to " .
"this server's catalog. Please make sure that you have been added to this server's access list.\n";
$encoded_array = old_xmlrpc_encode($result);
return new xmlrpcresp($encoded_array);
} // remote_server_deniee
?>

393
libglue/README Normal file
View file

@ -0,0 +1,393 @@
libglue - 8/17/03
libglue provides a set of libraries for use with applications
developed here at Oregon State University.
This set of libraries includes:
- mysql session handling,
- MySQL/LDAP/'shared' authentication methods
- a database handler
Contents:
1 Authentication Methods
1.1 LDAP Authentication
1.2 MySQL Authentication
1.3 Shared Authentication
2 Database schemas
2.1 For Session management
2.2 For LDAP Authentication
2.3 For MySQL Authentication
2.4 For Shared Authentication
3 The Config file
3.1 Formatting
3.2 Subsections
3.3 Arrays
3.3 Retrieving options
4 Session management
5 Libglue in action
6 Help, FAQs
1 Authentication Methods
--------------------------------------------------------------------------------
Libglue currently supports 3 authentication methods: LDAP, MySQL, and
'Shared.' It can support any combination of these concurrently, by falling
through in the order you specify (see Section 3.3).
1.1 LDAP Authentication
------------------------------------------------------------------------------
To use LDAP authentication, you must have LDAP support for PHP.
See http://php.net/manual/en/ref.ldap.php for how to configure php with LDAP.
You must provide credentials for your LDAP server in the config file.
Anonymous LDAP authentication is possible, but not with libglue today.
libglue has two functions for ldap authentication, both in 'LIBGLUE/auth.php':
mixed get_ldap_user($username [,$fields])
object auth_ldap($username,$password)
'auth_ldap' is intended for internal use, while 'get_ldap_user' is a utility
for app developers to use. Both have similar layouts:
- connect to ldap service
- bind to ldap with credential from config file
- search for '$username' in the space specified in the config file
- attempt to bind with supplied user credentials (auth_ldap only)
'get_ldap_user' returns an array of fields on success (if '$fields' is
not specified, it will return all the information for the specified user),
and an error string on failure.
'auth_ldap' returns an 'auth_response' object, with success indicated by
the value of auth_response->success. (This class is defined in 'auth.php').
'auth_ldap' is typically only going to be called from a login script.
'get_ldap_user' could be used when granting access to a new user.
Config Options:
ldap_host
ldap_auth_dn
ldap_user_dn
ldap_filter
ldap_pass
ldap_fields
ldap_version
1.2 MySQL Authentication
------------------------------------------------------------------------------
MySQL Authentication (like all of libglue) requires MySQL support in PHP.
It defaults to using the MySQL PASSWORD() function to check passwords, but
can also use PHP crypt() for compatability with other applications
(pam_mysql for example).
MySQL Authentication assumes the local database specified in the config file
is being used. It is possible to support a different database, but that
begins to duplicate functionality from Share Authentication (Section 1.3).
Config Options:
mysql_host
mysql_db
mysql_username
mysql_passwd
mysql_table
mysql_usercol
mysql_passcol
mysql_other
mysql_fields
'mysql_other' is an optional clause appended to the query.
Ex: mysql_other = "access = 'admin'"
'mysql_fields' is a comma separated list of the fields to return from
'mysql_table'
Ex: mysql_fields = 'id,username,email,homedir'
1.3 Shared Authentication
------------------------------------------------------------------------------
Because libglue uses a mysql database to store session info, it is possible
to share session information between applications, creating a "Single Sign
On" (SSO) framework for web applications. libglue supports this out of
the box, with the following assumptions:
1) The initial authentication is being handled elsewhere
2) "SSO" session data is stored in a mysql database.
3) The SSO database uses the schema described in Section 2.3.
libglue keeps track of the 'type' of authentication each session uses, so
can still use LDAP or MySQL authentication when also using SSO.
Config options:
sso_host
sso_db
sso_username
sso_pass
sso_table
sso_sid
sso_usercol
sso_expirecol
sso_length
sso_dbh_name
2 Database schemas
--------------------------------------------------------------------------------
Below are sample schemas for use with libglue. Mandatory fields are
indicated with a '*'. Unless stated otherwise, field NAMES can be set in
the config file.
2.1 For Session Management
------------------------------------------------------------------------------
CREATE TABLE session_data (
* id varchar(32) NOT NULL default '',
* username varchar(16) NOT NULL default '',
* expire int(10) unsigned NOT NULL default '0',
* type enum('sso','mysql','ldap') NOT NULL default 'sso',
* data text,
PRIMARY KEY (id))
This session table should work for any type of authentication you do.
'id' is an md5sum by default (as generated by php) but you can make
something else up if you've got the spare entropy. 'Type' obviously
only applies if you're using more than 1 type of authentication,
but the code assumes that it's present.
'data' is the field where serialized php data (from $_SESSION) is stored.
If you overflow this field, weird things may happen.
2.2 For LDAP Authentication
------------------------------------------------------------------------------
Basic LDAP authentication with libglue doesn't require a mysql database,
only session management. However, you will most likely need to store
some user information locally, in which case the table definition in
Section 2.3 is a good starting point.
2.3 For MySQL Authentication
------------------------------------------------------------------------------
CREATE TABLE user (
* id int(11) NOT NULL default '0',
* username varchar(255) NOT NULL default '',
* password varchar(255) default NULL,
fullname varchar(255) NOT NULL default '',
email varchar(255) default NULL,
status enum('disabled','enabled','dev') NOT NULL default 'enabled',
expire date default NULL,
phone varchar(255) NOT NULL default '',
PRIMARY KEY (id),
UNIQUE KEY username (username),
UNIQUE KEY id (id)
}
Feel free to add columns to this table and then specify them in
'mysql_fields' to make them part of your session data.
2.3 For Shared Authentication
------------------------------------------------------------------------------
If you need to store user data locally, see the definition in Section 2.3.
3 The Config file
--------------------------------------------------------------------------------
3.1 Formatting
------------------------------------------------------------------------------
The libglue config file is a lot like the smb.cnf file if you've ever used
samba (it's really easy to parse). Options are specified like
option = value
'option' is a letter followed by any number of letters or numbers.
The spaces between 'option' and 'value' are optional.
'value' may be single quoted, double quoted, or not quoted at all.
semicolons at the end of the line are ignored.
'#' is the single-line comment character.
3.2 Subsections
------------------------------------------------------------------------------
The config file parser can generate subsections in the config:
> [libglue]
> option1 = value;
> option2 = 'value';
> option3 = "value"
> [conf]
> option1 = value;
> otheroption = othervalue;
> [other]
> foo = "bar";
The parser then returns:
array(
'libglue' => ('option1' => 'value',
'option2' => 'value',
'option3' => 'value'),
'conf' => ('option1' => 'value',
'otheroption' => 'othervalue'),
'other' => ('foo' => 'bar')
);
3.3 Arrays
------------------------------------------------------------------------------
You can create arrays of values in the config file by declaring an option
multiple times:
[libglue]
ldap_fields = 'cn'
ldap_fields = 'homedirectory'
ldap_fields = 'uidnumber'
ldap_fields = 'uid'
ldap_fields = 'osuuid'
would return the following:
array(
'libglue' => ('ldap_fields' => (
0 => 'cn',
1 => 'homedirectory',
2 => 'uidnumber',
3 => 'uid',
4 => 'osuuid')
)
)
3.3 Retrieving options
------------------------------------------------------------------------------
LIBGLUE/config.php defines two functions, conf() and libglue_param() for
retrieving values from the config file. See "Libglue in action" below.
4 Session Data and Management
--------------------------------------------------------------------------------
Libglue should relieve some of the burden of session management from your app
once a user is authenticated. The config file has the following parameters,
user_data_name - Name of the array to store authentication session data in.
Ex:
user_data_name = 'user'
Libglue then puts all the account information it retrieves
into $_SESSION['user']
user_id - fieldname for userid,
stored in $_SESSION[user_data_name][user_id]
user_username - fieldname for username,
stored in $_SESSION[user_data_name][user_username]
Then for each of your authentication methods:
ldap_uidfield = 'uidnumber'
ldap_usernamefield = 'uid'
mysql_uidfield = 'id'
mysql_usernamefield = 'username'
Note that in this case, 'sso' isn't really an authentication method
(the info has to be looked up either in ldap or mysql).
What this lets you do is ignore account type in your application, since
every session will have the same field names.
5 Libglue in action
--------------------------------------------------------------------------------
Libglue assumes there are three basic types of files in your application:
1) Login/Authentication page
2) Restricted pages
3) Logout/Cleanup page
Example login and logout pages are in the LIBGLUE/examples directory.
For (2), you'll be calling the same code over and over. It is a good idea
to create an init file to take care of these common tasks in your application.
In each file, you'll do a
> $restricted = 1;
> require_once('/path/to/init.php');
right off the bat; libglue needs to run before anything else so it can send
HTTP headers for cookies and redirection if necessary.
Here is a sample init.php:
<?php
//config defines readconfig(), libglue_param(), and conf()
require_once("/data/libglue/config.php");
// 1st parameter is the path to the config file
// 2nd parameter is DEBUG (1 or 0)
// '$config' will hold the parsed config data
$config = read_config("/data/app/conf/config.conf",0);
// Register subsection 'libglue' in libglue_param()
libglue_param($config['libglue']);
//Register subsection 'app' in conf()
conf($config['app']);
//Require the rest of the libglue code:
// Authentication methods:
require_once('/data/libglue/auth.php');
// Session handling code:
require_once('/data/libglue/session.php');
// Common database handle:
require_once('/data/libglue/dbh.php');
// This is optional, if you have some pages where session data and
// authentication aren't relevant. Otherwise just do check_session().
if($restricted === 1) check_session();
?>
libglue_param() and conf() make use of static member variables and
tests on paramter types to register/retrieve config data. When passed an
array, these functions assume you're registering config options. If given
a string, as in:
$database_name = libglue_param('local_db');
the function will look for the key 'local_db' in the values that have been
previously registered with it. This is a little bit hokey, but objects
don't yet support static members in php so it's about the best we can do.
Session management is just taken care of; anything you put in $_SESSION in
your app is serialized, stored in the db when the page is done redering,
and retrieved on page load.
Database handle management is nice with libglue; if you've defined
'dbh' in the config file, you can call dbh() to use that database handle again:
$dbh = dbh();
mysql_query($sql, $dbh);
or
mysql_query($sql, dbh());
6 Help, FAQs
--------------------------------------------------------------------------------
Libglue is distributed at:
http://oss.oregonstate.edu/libglue/
as it becomes more mature and widely used, this page may include more help
documentation.
For now, feel free to email
cws-prog@lists.orst.edu
with any questions or bug reports.
-- Central Web Services,
Oregon State University

399
libglue/auth.php Normal file
View file

@ -0,0 +1,399 @@
<?
/* ------------------- CVS INFO ----------------------
*
* $Source: /data/cvsroot/ampache/libglue/auth.php,v $
* last modified by $Author: vollmerk $ at $Date: 2003/11/27 10:19:28 $
*
* Libglue, a free php library for handling authentication
* and session management.
*
* Written and distributed by Oregon State University.
* http://oss.oregonstate.edu/libglue
*
* ---------------------------------------------------
*/
//
// Attempt to authenticate using the services in
// auth_methods, and returns an auth_config object
// which describes the results of the authentication
// attempt
function authenticate($username, $password)
{
// First thing to do is check for the gone fishing file:
$stopfile = libglue_param('stop_auth');
if ( file_exists($stopfile) )
{
echo "We should tell the users here that no one can log in.\n";
exit();
}
$methods = libglue_param('auth_methods');
if(!is_array($methods))
{
$auth = call_user_func("auth_$methods",$username,$password);
}
else
{
foreach($methods as $method)
{
$auth = call_user_func("auth_$method", $username,$password);
if($auth['success'] == 1) break;
}
}
return $auth;
}
function get_ldap_user ($username,$fields=0)
{
$auth = array();
$auth_dn = libglue_param('ldap_auth_dn');
$user_dn = libglue_param('ldap_user_dn');
$filter = libglue_param('ldap_filter');
$host = libglue_param('ldap_host');
$pass = libglue_param('ldap_pass');
$ldapfields = libglue_param('ldap_fields');
$protocol = libglue_param('ldap_version');
// can we even connect?
if ( $ldap_link = @ldap_connect( $host ) )
{
//Snazzy new protocol stuff
if(!empty($protocol)) ldap_set_option($ldap_link,
LDAP_OPT_PROTOCOL_VERSION,
$protocol);
// now try and bind with system credentials for searching.
if ( @ldap_bind($ldap_link, $filter."".$auth_dn, $pass) )
{
// now search and retrieve our user data
$ldap_uid = libglue_param('ldap_uidfield');
$ldap_username = libglue_param('ldap_usernamefield');
//force uid and username to be part of the query
if(!in_array($ldap_uid,$ldapfields)) $ldapfields[] = $ldap_uid;
if(!in_array($ldap_username,$ldapfields)) $ldapfields[] = $ldap_username;
$sr = ldap_search($ldap_link, $user_dn, "(".$filter."".$username.")", $ldapfields, 0, 1);
/* $sr = @ldap_search($ldap_link, $user_dn, "(".$filter."".$username.")");*/
//info will contain a 1-element array with our user's info
$info = ldap_get_entries($ldap_link, $sr);
foreach($ldapfields as $field)
{
$auth[$field] = $info[0][$field][0];
}
$sess_username = libglue_param('user_username');
$sess_id = libglue_param('user_id');
$auth[$sess_username] = $username;
$auth[$sess_id] = $info[0][$ldap_uid][0];
}
//
// Here means we couldn't use the service.
// So it's most likely config related.
// Check the username and password?
//
else
{ $auth['error'] = libglue_param('bad_auth_cred'); }
}
//
// This most often will mean we can't reach the server.
// Perhaps it's down, or we mistyped the address.
//
else
{ $auth['error'] = libglue_param('connect_error'); }
// Done with the link, give it back
ldap_close($ldap_link);
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
if(in_array('sso',$auth_methods,TRUE)) $auth['type'] = 'sso';
else $auth['type'] = 'ldap';
return $auth;
}
function get_mysql_user ($username,$fields=null)
{
$auth = array();
$dbh = dbh();
$user_table = libglue_param('mysql_table');
$mysql_uid = libglue_param('mysql_uidfield');
$mysql_username = libglue_param('mysql_usernamefield');
$mysql_fields = libglue_param('mysql_fields');
$sql = "SELECT ";
if(is_null($fields)) $sql .= " * ";
else
{
if(!is_array($fields)) $fields = array($fields);
foreach($fields as $field)
{
$sql .= "$field,";
}
$sql = substr($sql, 0, strlen($sql)-1);
}
$sql .= " FROM $user_table WHERE $mysql_username = '$username'";
$result = mysql_query($sql, $dbh);
foreach($ldapfields as $field)
{
$auth[$field] = $info[0][$field][0];
}
$sess_username = libglue_param('user_username');
$sess_id = libglue_param('user_id');
$auth[$sess_username] = $username;
$auth[$sess_id] = $info[0][$ldap_uid][0];
$auth['type'] = 'mysql';
return $auth;
}
function auth_ldap ($username, $password)
{
$auth = array();
$auth['success'] = 0; // don't want to keep setting this
$auth_dn = libglue_param('ldap_auth_dn');
$user_dn = libglue_param('ldap_user_dn');
$filter = libglue_param('ldap_filter');
$host = libglue_param('ldap_host');
$pass = libglue_param('ldap_pass');
$ldapfields = libglue_param('ldap_fields');
// Did we get fed proper variables?
if(!$username || !$password)
{
$auth['error'] = libglue_param('empty_field');
// I'm not a huge fan of returning here,
// but why force more logic?
return $auth;
}
// can we even connect?
if ( $ldap_link = @ldap_connect( $host ) )
{
// now try and bind with system credentials for searching.
if ( @ldap_bind($ldap_link, $filter."".$auth_dn, $pass) )
{
// now search and retrieve our user data
$ldap_uid = libglue_param('ldap_uidfield');
$ldap_username = libglue_param('ldap_usernamefield');
//force uid and username to be part of the query
if(!in_array($ldap_uid,$ldapfields)) $ldapfields[] = $ldap_uid;
if(!in_array($ldap_username,$ldapfields)) $ldapfields[] = $ldap_username;
$sr = ldap_search($ldap_link, $user_dn, "(".$filter."".$username.")", $ldapfields, 0, 1);
//info will contain a 1-element array with our user's info
$info = @ldap_get_entries($ldap_link, $sr);
//
// The real authentication:
// binding here with the user's credentials
//
//if ( ldap_bind($ldap_link, $user_dn, $password) ) {
if ( ($info["count"] == 1) && (@ldap_bind($ldap_link,
$info[0]['dn'],
$password) ) )
{
$auth['info'] = array();
foreach($ldapfields as $field)
{
$auth['info'][$field] = $info[0][$field][0];
}
$sess_username = libglue_param('user_username');
$sess_id = libglue_param('user_id');
$auth['info'][$sess_username] = $username;
$auth['info'][$sess_id] = $info[0][$ldap_uid][0];
$auth['success'] = 1;
}
else
{
// show the error here, better than anything I can come up with
// most likely bad username or password
// We'll handle two cases, where the username doesn't exist,
// and where more than 1 exists separately in case we
// decide to do some logging or something fancy someday
if($info["count"] == 0)
{
$auth['error'] = libglue_param('login_failed');
}
else
{
// We could return the error here
// EXCEPT that we want the error message to be the same
// for a bad password as a bad username
// $auth->error = ldap_error($ldap_link);
$auth['error'] = libglue_param('login_failed');
}
}
}
//
// Here means we couldn't use the service.
// So it's most likely config related.
// Check the username and password?
//
else
{
$auth['error'] = libglue_param('bad_auth_cred');
}
}
//
// This most often will mean we can't reach the server.
// Perhaps it's down, or we mistyped the address.
//
else
{
$auth['error'] = libglue_param('connect_error');
}
// Done with the link, give it back
ldap_close($ldap_link);
$auth['type'] = 'ldap';
return $auth;
}
/*
* MySQL authentication.
* returns true/false depending on whether the user was authenticated
* successfully
* The crypt settings below assume the php crypt() function created the passwords.
* But hopson updated it to use mysql PASSWORD() instead
*/
function auth_mysql($username, $password) {
$auth = array();
$auth['success'] = 0;
// Did we get fed proper variables?
if(!$username or !$password) {
$auth['error'] = 'Empty username/password';
return $auth;
}
//
// Retrieve config parameters set in config.php
//
$dbhost = libglue_param('mysql_host');
$dbuser = libglue_param('mysql_user');
$dbpass = libglue_param('mysql_pass');
$dbname = libglue_param('mysql_db');
$passfield = libglue_param('mysql_passcol');
$table = libglue_param('mysql_table');
$usercol = libglue_param('mysql_usercol');
$other = libglue_param('mysql_other');
$fields = libglue_param('mysql_fields');
$mysql_uidfield = libglue_param('mysql_uidfield');
$mysql_usernamefield = libglue_param('mysql_usernamefield');
if(!preg_match("/$mysql_uidfield/",$fields)) $fields .= ",$mysql_uidfield";
if(!preg_match("/$mysql_usernamefield/",$fields)) $fields .= ",$mysql_usernamefield";
if($other == '') $other = '1=1';
if ($mysql_link = @mysql_connect($dbhost,$dbuser,$dbpass))
{
//
// now retrieve the stored password to use as salt
// for password checking
//
$sql = "SELECT $passfield FROM $table" .
" WHERE $usercol = '$username' " .
" AND $other LIMIT 1";
@mysql_select_db($dbname, $mysql_link);
$result = @mysql_query($sql, $mysql_link);
$row = @mysql_fetch_array($result);
$password_check_sql = "PASSWORD('$password')";
$sql = "SELECT version()";
$db_results = @mysql_query($sql, $mysql_link);
$version = @mysql_fetch_array($db_results);
$mysql_version = substr(preg_replace("/(\d+)\.(\d+)\.(\d+).*/","$1$2$3",$version[0]),0,3);
if ($mysql_version > "409" AND substr($row[0],0,1) !== "*") {
$password_check_sql = "OLD_PASSWORD('$password')";
}
$sql = "SELECT $fields FROM $table" .
" WHERE $usercol = '$username'" .
" AND $passfield = $password_check_sql" .
" AND $other LIMIT 1";
$rs = @mysql_query($sql, $mysql_link);
//This should only fail on a badly formed query.
if(!$rs)
{
$auth['error'] = @mysql_error();
}
//
// Retrieved the right info, set auth->success and info.
//
if (@mysql_num_rows($rs) == 1)
{
// username and password are successful
$row = mysql_fetch_array($rs);
$sess_username = libglue_param('user_username');
$sess_id = libglue_param('user_id');
$auth[$info][$sess_username] = $row[$mysql_usernamefield];
$auth[$info][$sess_id] = $row[$mysql_uidfield];
$auth[$info] = $row;
$auth['info'] = $row;
$auth['success'] = 1;
}
//
// We didn't find anything matching. No user, bad password, ?
//
else
{
$auth['error'] = libglue_param('login_failed');
}
}
//
// Couldn't connect to database at all.
//
else
{
$auth['error'] = libglue_param('bad_auth_cred');
}
$auth['type'] = 'mysql';
return $auth;
} // auth_mysql
function auth_sso ($username, $password)
{
$auth = new auth_response();
$auth->success = 0;
$auth->error = "SSO Authentication failed.";
return $auth;
}
// This is the auth_response class that will be returned during
// and authentication - this allows us to set some variables
// by the session for later lookup
class auth_response {
var $username;
var $userid;
var $error;
var $success;
var $info;
}
?>

173
libglue/config.php Normal file
View file

@ -0,0 +1,173 @@
<?php
function read_config($config_file, $debug = 0) {
$fp = fopen($config_file,'r');
if(!is_resource($fp)) die("Can't open config file $config_file");
$file_data = fread($fp,filesize($config_file));
fclose($fp);
// explode the var by \n's
$data = explode("\n",$file_data);
if($debug) echo "<pre>";
$count = 0;
$config_name = '';
foreach($data as $value)
{
$count++;
if (preg_match("/^\[([A-Za-z]+)\]$/",$value,$matches))
{
// If we have previous data put it into $results...
if (!empty($config_name) && count(${$config_name})) $results[$config_name] = ${$config_name};
$config_name = $matches[1];
} // if it is a [section] name
elseif ($config_name)
{
// if it's not a comment
if (preg_match("/^(\w[\w\d]*)\s*=\s*\"{1}(.*?)\"{1};*$/",$value,$matches)
|| preg_match("/^(\w[\w\d]*)\s*=\s*\'{1}(.*?)\'{1};*$/", $value, $matches)
|| preg_match("/^(\w[\w\d]*)\s*=\s*[\'\"]{0}(.*)[\'\"]{0};*$/",$value,$matches))
{
if (isset(${$config_name}[$matches[1]]) && is_array(${$config_name}[$matches[1]]) && isset($matches[2]) )
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push(${$config_name}[$matches[1]], $matches[2]);
}
elseif (isset(${$config_name}[$matches[1]]) && isset($matches[2]) )
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
${$config_name}[$matches[1]] = array(${$config_name}[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "")
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
${$config_name}[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0)
{
echo "Error Invalid Config Entry --> Line:$count"; die;
} // else if it's not a comment and there is something there
else
{
if($debug)
echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end if it's not a comment
} // else if no config_name
elseif (preg_match("/^([\w\d]+)\s+=\s+[\"]{1}(.*?)[\"]{1}$/",$value,$matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\']{1}(.*?)[\']{1}$/", $value, $matches)
|| preg_match("/^([\w\d]+)\s+=\s+[\'\"]{0}(.*)[\'\"]{0}$/",$value,$matches))
{
if (is_array($results[$matches[1]]) && isset($matches[2]) )
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> to existing key <strong>$matches[1]</strong>\n";
array_push($results[$matches[1]], $matches[2]);
}
elseif (isset($results[$matches[1]]) && isset($matches[2]) )
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> to existing key $matches[1]</strong>\n";
$results[$matches[1]] = array($results[$matches[1]],$matches[2]);
}
elseif ($matches[2] !== "")
{
if($debug)
echo "Adding value <strong>$matches[2]</strong> for key <strong>$matches[1]</strong>\n";
$results[$matches[1]] = $matches[2];
}
// if there is something there and it's not a comment
elseif ($value{0} !== "#" AND strlen(trim($value)) > 0)
{
echo "Error Invalid Config Entry --> Line:$count"; die;
} // else if it's not a comment and there is something there
else
{
if($debug)
echo "Key <strong>$matches[1]</strong> defined, but no value set\n";
}
} // end else
} // foreach
if (count(${$config_name}))
{
$results[$config_name] = ${$config_name};
}
if($debug) echo "</pre>";
return $results;
} // end read_config
function libglue_param($param,$clobber=0)
{
static $params = array();
if(is_array($param))
//meaning we are setting values
{
foreach ($param as $key=>$val)
{
if(!$clobber && isset($params[$key]))
{
echo "Error: attempting to clobber $key = $val\n";
exit();
}
$params[$key] = $val;
}
return true;
}
else
//meaning we are trying to retrieve a parameter
{
if(isset($params[$param])) return $params[$param];
else return false;
}
}
function conf($param,$clobber=0)
{
static $params = array();
if(is_array($param))
//meaning we are setting values
{
foreach ($param as $key=>$val)
{
if(!$clobber && isset($params[$key]))
{
echo "Error: attempting to clobber $key = $val\n";
exit();
}
$params[$key] = $val;
}
return true;
}
else
//meaning we are trying to retrieve a parameter
{
if(isset($params[$param])) return $params[$param];
else return false;
}
}
function dbh($str='')
{
if($str !== '') $dbh = libglue_param(libglue_param($str));
else $dbh = libglue_param(libglue_param('dbh'));
if(!is_resource($dbh)) die("Bad database handle: $dbh");
else return $dbh;
}

53
libglue/dbh.php Normal file
View file

@ -0,0 +1,53 @@
<?
/*
* ---------------------------- CVS INFO --------------------------------
*
* $Source: /data/cvsroot/ampache/libglue/dbh.php,v $
* last modified by $Author: vollmerk $ at $Date: 2003/11/24 05:53:13 $
*
* Libglue, a free php library for handling authentication
* and session management.
*
* Written and distributed by Oregon State University.
* http://oss.oregonstate.edu/libglue
*
* -----------------------------------------------------------------------
*/
/*----------------------------------------------------------------------
For complete information on this toolkit see the README located in this
directory.
This is the database handler class. This will setup and return a
database handle for use in your application. Simply pass it a
username and password. If an error occurs you'll be presented with
a verbose reason for the error.
----------------------------------------------------------------------*/
function setup_sess_db($name, $host, $db, $username, $password)
{
$dbh = @mysql_connect($host, $username, $password) or header("Location:" . conf('web_path') . "/test.php");
if ( !is_resource($dbh) )
{
echo "Unable to connect to \"". $host ."\" in order to \n" .
"use the \"". $db ."\" database with account \"".$username." : ".$password.
"\"\n . Perhaps the database is not " .
"running, \nor perhaps the admin needs to change a few variables in\n ".
"the config files in order to point to the correct database.\n";
echo "Details: " .
mysql_errno() . ": " .
mysql_error() . "\n";
die();
}
else
{
@mysql_select_db($db, $dbh) or header("Location:" . conf('web_path') . "/test.php");
libglue_param(array($name=>$dbh));
}
return $dbh;
}
?>

95
libglue/libdb.php Normal file
View file

@ -0,0 +1,95 @@
<?php
//
// PHP itself sort of supports the behavior defined here,
// but I don't trust it, and I think it's better to do
// application-level database abstraction.
//
function db_connect($host='localhost',$user=null,$password=null)
{
static $dbh = null;
// If we haven't already connected, do so
// The first call must include this info
// Subsequent calls that provide this info may bork db_query() below if you're not careful,
// but until I can have static class variables, I'm not going to make an object
// out of this mojo.
if(!empty($host) && isset($user) && isset($password)) $dbh = @mysql_connect($host,$user,$password);
// If we've already connected successfully, we're good
if(is_resource($dbh)){ return $dbh; }
// On a failed connection, let's just die?
else die("Unable to create database connection in db_connect()");
}
function db_makeinsert($vars, $table)
{
static $tables = array();
$dbh = db_connect();
if(!isset($tables[$table])) $tables[$table] = db_describe($table);
$fields = $tables[$table];
foreach($fields as $field)
{
//only addslashes if magic quotes is off
if(get_magic_quotes_gpc) $vars[$field['Field']] = stripslashes($vars[$field['Field']]);
addslashes($vars[$field['Field']]);
if(isset($vars[$field['Field']]))
{
$q1 = isset($q1)? $q1.','.$field['Field']:'INSERT INTO '.$table.'('.$field['Field'];
$q2 = isset($q2)? $q2.",\"".$field[$var['Field']]."\"":" VALUES(\"".$vars[$field['Field']]."\"";
}
}
$q1.=')';
$q2.=')';
$query = $q1.$q2;
return $query;
}
function db_select($database, $dbh=null)
{
if(is_resource($dbh)) @mysql_select_db($database);
else @mysql_select_db($database, db_connect());
}
function db_describe($thingy)
{
$descriptions = array();
foreach( (explode(',',$thingy)) as $field)
{
db_query("DESCRIBE $field");
while($row = db_fetch()){ $descriptions[] = $row; }
}
return $descriptions;
}
function db_query($qry=null, $dbh=null)
{
static $result = null;
if(!is_resource($dbh)) $dbh = db_connect();
if(is_null($qry))
{
if(is_resource($result)) return $result;
else return false;
}
else
{
$result = @mysql_query($qry, $dbh);
return $result;
}
}
function db_fetch($result=null)
{
if(!is_resource($result)) return @mysql_fetch_array(db_query());
else return @mysql_fetch_array($result);
}
function db_scrub($var,$htmlok=false)
{
if(!get_magic_quotes_gpc()) $var = addslashes($var);
return $var;
}

417
libglue/session.php Normal file
View file

@ -0,0 +1,417 @@
<?
/* ------------------- CVS INFO ----------------------
*
* $Source: /data/cvsroot/ampache/libglue/session.php,v $
* last modified by $Author: vollmerk $ at $Date: 2003/11/24 05:53:13 $
*
* Libglue, a free php library for handling authentication
* and session management.
*
* Written and distributed by Oregon State University.
* http://oss.oregonstate.edu/libglue
*
* ---------------------------------------------------
*/
function check_sess_db($dbtype = 'local')
{
if($dbtype === 'sso')
{
$dbh = libglue_param(libglue_param('sso_dbh_name'));
if(is_resource($dbh)) return $dbh;
$dbh_name = libglue_param('sso_dbh_name');
$host = libglue_param('sso_host');
$db = libglue_param('sso_db');
$user = libglue_param('sso_username');
$pass = libglue_param('sso_pass');
$name = libglue_param('sso_dbh_name');
}
elseif($dbtype === 'local')
{
$dbh = libglue_param(libglue_param('local_dbh_name'));
if(is_resource($dbh)) return $dbh;
$dbh_name = libglue_param('local_dbh_name');
$host = libglue_param('local_host');
$db = libglue_param('local_db');
$user = libglue_param('local_username');
$pass = libglue_param('local_pass');
$name = libglue_param('local_dhb_name');
}
$dbh = setup_sess_db($dbh_name,$host,$db,$user,$pass);
if(is_resource($dbh)) return $dbh;
else die("Could not connect to $dbtype database for session management");
}
//
// Really we are just checking the session here -- we want to see if
// if the user has a valid session, if they do then we'll let them do
// what they need to do.
//
function check_session($id=0)
{
//If an id isn't passed in, retrieve one from the cookie
if($id===0) {
/*
We don't need to set cookie params here php
is smart enough to know which cookie it wants
via the session_name. Setting cookie params
here sometimes made php create a new cookie
which is very bad :) -- Vollmer
*/
$name = libglue_param('sess_name');
if($name) session_name($name);
// Start the session, then get the cookie id
session_start();
$id = strip_tags($_COOKIE[$name]);
}
// Determine if we need to check the SSO database:
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
$sso_mode = in_array('sso',$auth_methods,TRUE);
$local = get_local_session($id);
if($sso_mode) $sso = get_sso_session($id);
if($sso_mode && !$sso)
{
return FALSE;
}
else if ($sso_mode && is_array($sso))
{
if(is_array($local)) return TRUE;
else
{
//
// Should we do gc here, just in case
// local is only expired?
// (The insert in make_local_session
// will fail if we don't)
//
$newlocal = make_local_session_sso($sso);
return $newlocal;
}
}
//If we get here, we're not using SSO mode
else if (!is_array($local))
{
return FALSE;
}
else return TRUE;
}
function make_local_session_only($data,$id=0)
{
if($id===0)
{
$name = libglue_param('sess_name');
$domain = libglue_param('sess_domain');
if($name) session_name($name);
//Lifetime of the cookie:
$cookielife = libglue_param('sess_cookielife');
if(empty($cookielife)) $cookielife = 0;
//Secure cookie?
$cookiesecure = libglue_param('sess_cookiesecure');
if(empty($cookiesecure)) $cookiesecure = 0;
//Cookie path:
$cookiepath = libglue_param('sess_cookiepath');
if(empty($cookiepath)) $cookiepath = '/';
if(!empty($domain)) session_set_cookie_params($cookielife,$cookiepath,$domain,$cookiesecure);
// Start the session
session_start();
/*
Before a refresh we do not have a cookie value
here so let's use session_id() --Vollmer
*/
$id = session_id();
}
$userfield = libglue_param('user_username');
$username = $data['info'][$userfield];
$type = $data['type'];
$local_dbh = check_sess_db('local');
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$local_usercol = libglue_param('local_usercol');
$local_datacol = libglue_param('local_datacol');
$local_expirecol = libglue_param('local_expirecol');
$local_typecol = libglue_param('local_typecol');
$sql= "INSERT INTO $local_table ".
" ($local_sid,$local_usercol,$local_typecol)".
" VALUES ('$id','$username','$type')";
$db_result = mysql_query($sql, $local_dbh);
if($db_result) return TRUE;
else return FALSE;
}
function make_local_session_sso($sso_session)
{
$sso_usercol = $sso_session[libglue_param('sso_usercol')];
$sso_sid = $sso_session[libglue_param('sso_sid')];
$sso_expire = $sso_session[libglue_param('sso_expirecol')];
$user = get_ldap_user($sso_usercol);
$data = array('user'=>$user);
//Somewhat stupidly, we have to initialize $_SESSION here,
// or sess_write will blast it for us
$_SESSION = $data;
$db_data = serialize($data);
$local_dbh = check_sess_db('local');
//Local stuff we need:
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$local_usercol = libglue_param('local_usercol');
$local_datacol = libglue_param('local_datacol');
$local_expirecol = libglue_param('local_expirecol');
$local_typecol = libglue_param('local_typecol');
$sql= "INSERT INTO $local_table ".
" ($local_sid,$local_usercol,$local_datacol,$local_expirecol,$local_typecol)".
" VALUES ('$sso_sid','$sso_usercol','$db_data','$sso_expire','sso')";
$db_result = mysql_query($sql, $local_dbh);
if($db_result) return TRUE;
else return FALSE;
}
function get_local_session($sid)
{
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$local_expirecol = libglue_param('local_expirecol');
$local_length = libglue_param('local_length');
$local_usercol = libglue_param('local_usercol');
$local_datacol = libglue_param('local_datacol');
$local_typecol = libglue_param('local_typecol');
$local_dbh = check_sess_db('local');
$time = time();
$sql = "SELECT * FROM $local_table WHERE $local_sid='$sid' AND $local_expirecol > $time";
$db_result = mysql_query($sql, $local_dbh);
$session = mysql_fetch_array($db_result);
if(is_array($session)) $retval = $session;
else $retval = FALSE;
if($retval === FALSE)
{
//Find out what's going on
}
return $retval;
}
function get_sso_session($sid)
{
$sso_table = libglue_param('sso_table');
$sso_sid = libglue_param('sso_sid');
$sso_expirecol = libglue_param('sso_expirecol');
$sso_length = libglue_param('sso_length');
$sso_usercol = libglue_param('sso_usercol');
$sso_dbh = check_sess_db('sso');
$time = time();
$sql = "SELECT * FROM $sso_table WHERE $sso_sid='$sid' AND $sso_expirecol > $time";
$db_result = mysql_query($sql, $sso_dbh);
$sso_session = mysql_fetch_array($db_result);
$retval = (is_array($sso_session))?$sso_session:FALSE;
return $retval;
}
// This will start the session tools, then destroy anything in the database then
// clear all of the session information
function logout ($id=0)
{
sess_destroy($id);
$login_page = libglue_param('login_page');
// should clear both the database information as well as the
// current session info
header("Location: $login_page");
die();
return true;
}
// Double checks that we have a database handle
// Args are completely ignored - we're using a database here
function sess_open($save_path, $session_name)
{
$local_dbh = check_sess_db();
if ( !is_resource($local_dbh) )
{
echo "<!-- Unable to connect to local server in order to " .
"use the session database. Perhaps the database is not ".
"running, or perhaps the admin needs to change a few variables in ".
"the config file in order to point to the correct ".
"database.-->\n";
return FALSE;
}
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
if(in_array('sso',$auth_methods,TRUE))
{
$sso_dbh = check_sess_db('sso');
if ( !is_resource($sso_dbh) )
{
echo "<!-- Unable to connect to the SSO server in order to " .
"use the session database. Perhaps the database is not ".
"running, or perhaps the admin needs to change a few variables in ".
"modules/include/global_settings in order to point to the correct ".
"database.-->\n";
return FALSE;
}
}
return TRUE;
}
// Placeholder function, does nothing
function sess_close()
{
return true;
}
// Retrieve session identified by 'key' from the database
// and return the data field
function sess_read($key)
{
$retval = 0;
$session = get_local_session($key);
$datacol = libglue_param('local_datacol');
if(is_array($session)) $retval = $session[$datacol];
else $retval = "";
return $retval;
}
//
// Save the session data $val to the database
//
function sess_write($key, $val)
{
$local_dbh = check_sess_db('local');
$local_datacol = libglue_param('local_datacol');
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$auth_methods = libglue_param('auth_methods');
$local_expirecol = libglue_param('local_expirecol');
$local_length = libglue_param('local_length');
$time = $local_length+time();
// If they've got the long session
if ($_COOKIE['amp_longsess'] == '1') {
$time = time() + 86400*364;
}
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
if(!in_array('sso',$auth_methods,TRUE))
{
// If not using sso, we now need to update the expire time
$sql = "UPDATE $local_table SET $local_datacol='" . sql_escape($val) . "',$local_expirecol='$time'".
" WHERE $local_sid = '$key'";
}
else $sql = "UPDATE $local_table SET $local_datacol='" . sql_escape($val) . "',$local_expirecol='$time'".
" WHERE $local_sid = '$key'";
return mysql_query($sql, $local_dbh);
}
//
// Remove the current session from the database.
//
function sess_destroy($id=0)
{
if($id == 0) {
session_start();
$id = session_id();
}
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
if(in_array('sso',$auth_methods,TRUE))
{
$sso_sid = libglue_param('sso_sid');
$sso_table = libglue_param('sso_table');
$sso_dbh = check_sess_db('sso');
$sql = "DELETE FROM $sso_table WHERE $sso_sid = '$id' LIMIT 1";
$result = mysql_query($sql, $sso_dbh);
}
$local_sid = libglue_param('local_sid');
$local_table = libglue_param('local_table');
$local_dbh = check_sess_db('local');
$sql = "DELETE FROM $local_table WHERE $local_sid = '$id' LIMIT 1";
$result = mysql_query($sql, $local_dbh);
$_SESSION = array();
/* Delete the long ampache session cookie */
setcookie ("amp_longsess", "", time() - 3600);
/* Delete the ampache cookie as well... */
setcookie (libglue_param('sess_name'),"", time() - 3600);
return TRUE;
}
//
// This function is called with random frequency
// to remove expired session data
//
function sess_gc($maxlifetime)
{
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
if(in_array('sso',$auth_methods,TRUE))
{
//Delete old sessions from SSO
// We do 'where length' so we don't accidentally blast
// another app's sessions
$sso_expirecol = libglue_param('sso_expirecol');
$sso_table = libglue_param('sso_table');
$sso_length = libglue_param('sso_length');
$local_length = libglue_param('local_length');
$sso_dbh = check_sess_db('sso');
$time = time();
$sql = "DELETE FROM $sso_table WHERE $sso_expirecol < $time".
" AND $sso_length = '$local_length'";
$result = mysql_query($sql, $sso_dbh);
}
$local_expirecol = libglue_param('local_expirecol');
$local_table = libglue_param('local_table');
$time = time();
$local_dbh = check_sess_db('local');
$sql = "DELETE FROM $local_table WHERE $local_expirecol < $time";
$result = mysql_query($sql, $local_dbh);
return true;
}
//
// Register all our cool session handling functions
//
session_set_save_handler(
"sess_open",
"sess_close",
"sess_read",
"sess_write",
"sess_destroy",
"sess_gc");
?>

346
libglue/session2.php Normal file
View file

@ -0,0 +1,346 @@
<?php
require_once('libdb.php');
function libglue_sess_db($dbtype = 'local')
{
if($dbtype === 'sso')
{
$dbh = libglue_param(libglue_param('sso_dbh_name'));
if(is_resource($dbh)) return $dbh;
$dbh_name = libglue_param('sso_dbh_name');
$host = libglue_param('sso_host');
$db = libglue_param('sso_db');
$user = libglue_param('sso_username');
$pass = libglue_param('sso_pass');
$name = libglue_param('sso_dbh_name');
}
elseif($dbtype === 'local')
{
$dbh = libglue_param(libglue_param('local_dbh_name'));
if(is_resource($dbh)) return $dbh;
$dbh_name = libglue_param('local_dbh_name');
$host = libglue_param('local_host');
$db = libglue_param('local_db');
$user = libglue_param('local_username');
$pass = libglue_param('local_pass');
$name = libglue_param('local_dhb_name');
}
$dbh = db_connect($host,$user,$pass);
db_select($db);
libglue_param(array($dbh_name=>$dbh));
if(is_resource($dbh)) return $dbh;
else die("Could not connect to $dbtype database for session management");
}
/* This function is public */
function check_session($id=null)
{
if(is_null($id))
{
//From Karl Vollmer, vollmerk@net.orst.edu:
// naming the session and starting it is sufficient
// to retrieve the cookie
$name = libglue_param('sess_name');
if(!empty($name)) session_name($name);
session_start();
$id = strip_tags($_COOKIE[$name]);
}
// Now what we have a session id, let's verify it:
if(libglue_sso_mode())
{
// if sso mode, we must have a valid sso session already
$sso_sess = libglue_sso_check($id);
if(!is_null($sso_sess))
{
// if sso is valid, it's okay to create a new local session
if($local_sess = libglue_local_check($id))
{
return true;
}
else
{
libglue_local_create($id,
$sso_sess[libglue_param('sso_username_col')],
'sso',
$sso_sess[libglue_param('sso_expire_col')]);
return true;
}
}
else
// libglue_sso_check failed
{
libglue_sess_destroy($id);
return false;
}
}
else
{
//if not in sso mode, there must be a local session
if($local_sess = libglue_local_check($id))
{
return true;
}
else
{
//you're gone buddy
libglue_sess_destroy($id);
return false;
}
}
}
// private function, don't ever use this:
function libglue_sso_mode()
{
$auth_methods = libglue_param('auth_methods');
if(!is_array($auth_methods)) $auth_methods = array($auth_methods);
return (in_array('sso',$auth_methods))?true:false;
}
function libglue_sso_check($sess_id)
{
// Read the sso info from the config file:
$sso_table = libglue_param('sso_table');
$sso_sid = libglue_param('sso_sessid_col');
$sso_expire_col = libglue_param('sso_expire_col');
$sso_length = libglue_param('sso_length');
$sso_username_col = libglue_param('sso_username_col');
$sso_dbh = libglue_sess_db('sso');
$sql = "SELECT * FROM $sso_table WHERE $sso_sid='$sess_id' AND $sso_expire_col > UNIX_TIMESTAMP()";
$db_result = db_query($sql, $sso_dbh);
if(is_resource($db_result)) $sso_session = db_fetch($db_result);
else $sso_session = null;
$retval = (is_array($sso_session))?$sso_session:null;
return $retval;
}
function libglue_local_check($sess_id)
{
static $retval = -1;
if($retval != -1) return $retval;
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$local_expirecol = libglue_param('local_expirecol');
$local_length = libglue_param('local_length');
$local_usercol = libglue_param('local_usercol');
$local_datacol = libglue_param('local_datacol');
$local_typecol = libglue_param('local_typecol');
$local_dbh = libglue_sess_db('local');
$sql = "SELECT $local_datacol FROM $local_table WHERE $local_sid='$sess_id' AND $local_expirecol > UNIX_TIMESTAMP()";
$db_result = db_query($sql, $local_dbh);
if(is_resource($db_result)) $session = db_fetch($db_result);
else $session = null;
if(is_array($session))
{
$retval = $session[$local_datacol];
}
else $retval = null;
return $retval;
}
function libglue_local_create($sess_id, $username, $type, $expire)
{
if($type === "sso" || $type === "ldap")
$userdata = get_ldap_user($username);
else if($type === "mysql")
$userdata = get_mysql_user($username);
$data = array(libglue_param('user_data_name')=>$userdata);
// It seems we have to set $_SESSION manually, or it gets blasted
// by php's session write handler
$_SESSION = $data;
$db_data = serialize($data);
$local_dbh = libglue_sess_db('local');
// Local parameters we need:
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$local_usercol = libglue_param('local_usercol');
$local_datacol = libglue_param('local_datacol');
$local_expirecol = libglue_param('local_expirecol');
$local_typecol = libglue_param('local_typecol');
// session data will be saved when the script terminates,
// but not the rest of this fancy info
$sql= "INSERT INTO $local_table ".
" ($local_sid,$local_usercol,$local_datacol,$local_expirecol,$local_typecol)".
" VALUES ('$sess_id','$username','$db_data','$expire','$type')";
$db_result = db_query($sql, $local_dbh);
if(!$db_result) die("Died trying to create local session: <pre><br>$sql</pre>");
}
function sess_open()
{
if(libglue_sso_mode())
{
if(!is_resource(libglue_sess_db('sso')))
{
die("<!-- Unable to connect to the SSO server in order to " .
"use the session database. Perhaps the database is not ".
"running, or perhaps the admin needs to change a few variables in ".
"modules/include/global_settings in order to point to the correct ".
"database.-->\n");
return false;
}
}
if(!is_resource(libglue_sess_db('local')))
{
die("<!-- Unable to connect to local server in order to " .
"use the session database. Perhaps the database is not ".
"running, or perhaps the admin needs to change a few variables in ".
"the config file in order to point to the correct ".
"database.-->\n");
return false;
}
return true;
}
function sess_close(){ return true; }
function sess_write($sess_id, $sess_data)
{
$local_dbh = libglue_sess_db('local');
$local_datacol = libglue_param('local_datacol');
$local_table = libglue_param('local_table');
$local_sid = libglue_param('local_sid');
$auth_methods = libglue_param('auth_methods');
$local_expire = libglue_param('local_expirecol');
$local_length = libglue_param('local_length');
$time = $local_length+time();
// If not using sso, we now need to update the expire time
$local_expire = libglue_param('local_expirecol');
$local_length = libglue_param('local_length');
$time = $local_length+time();
$sql = "UPDATE $local_table SET $local_datacol='$sess_data',$local_expire='$time'".
" WHERE $local_sid = '$sess_id'";
db_query($sql, $local_dbh);
if(libglue_sso_mode())
{
$sso_table = libglue_param('sso_table');
$sso_expire_col = libglue_param('sso_expire_col');
$sso_sess_length = libglue_param('sso_length_col');
$sso_sess_id = libglue_param('sso_sessid_col');
$time = time();
$sql = "UPDATE $sso_table SET $sso_expire_col = $sso_sess_length + UNIX_TIMESTAMP() WHERE $sso_sess_id = '$sess_id'";
$sso_dbh = libglue_sess_db('sso');
db_query($sql, $sso_dbh);
}
return true;
}
//
// This function is called with random frequency
// to remove expired session data
//
function sess_gc($maxlifetime)
{
if(libglue_sso_mode())
{
//Delete old sessions from SSO
// We do 'where length' so we don't accidentally blast
// another app's sessions
$sso_expirecol = libglue_param('sso_expire_col');
$sso_table = libglue_param('sso_table');
$sso_length = libglue_param('sso_length_col');
$local_length = libglue_param('local_length');
$sso_dbh = libglue_sess_db('sso');
$time = time();
$sql = "DELETE FROM $sso_table WHERE $sso_expirecol < $time".
" AND $sso_length = '$local_length'";
$result = db_query($sql, $sso_dbh);
}
$local_expire = libglue_param('local_expire');
$local_table = libglue_param('local_table');
$time = time();
$local_dbh = libglue_sess_db('local');
$sql = "DELETE FROM $local_table WHERE $local_expire < $time";
$result = db_query($sql, $local_dbh);
return true;
}
function libglue_sess_destroy($id=null)
{
if(is_null($id))
{
//From Karl Vollmer, vollmerk@net.orst.edu:
// naming the session and starting it is sufficient
// to retrieve the cookie
$name = libglue_param('sess_name');
if(!empty($name)) session_name($name);
session_start();
$id = strip_tags($_COOKIE[$name]);
}
if(libglue_sso_mode())
{
$sso_sid = libglue_param('sso_sessid_col');
$sso_table = libglue_param('sso_table');
$sso_dbh = libglue_sess_db('sso');
$sql = "DELETE FROM $sso_table WHERE $sso_sid = '$id' LIMIT 1";
$result = db_query($sql, $sso_dbh);
}
$local_sid = libglue_param('local_sid');
$local_table = libglue_param('local_table');
$local_dbh = libglue_sess_db('local');
$sql = "DELETE FROM $local_table WHERE $local_sid = '$id' LIMIT 1";
$result = db_query($sql, $local_dbh);
// It is very important we destroy our current session cookie,
// because if we don't, a person won't be able to log in again
// without closing their browser - SSO doesn't respect
//
// Code from http://php.oregonstate.edu/manual/en/function.session-destroy.php,
// Written by powerlord@spamless.vgmusic.com, 18-Nov-2002 08:41
//
$cookie = session_get_cookie_params();
if ((empty($cookie['domain'])) && (empty($cookie['secure'])) )
{
setcookie(session_name(), '', time()-3600, $cookie['path']);
} elseif (empty($CookieInfo['secure'])) {
setcookie(session_name(), '', time()-3600, $cookie['path'], $cookie['domain']);
} else {
setcookie(session_name(), '', time()-3600, $cookie['path'], $cookie['domain'], $cookie['secure']);
}
// end powerloard
unset($_SESSION);
unset($_COOKIE[session_name()]);
return TRUE;
}
function logout($id=null)
{
libglue_sess_destroy($id);
$login_page = libglue_param('login_page');
header("Location: $login_page");
die();
return true; //because why not?
}
//
// Register all our cool session handling functions
//
session_set_save_handler(
"sess_open",
"sess_close",
"libglue_local_check",
"sess_write",
"libglue_sess_destroy",
"sess_gc");
?>

124
locale/base/TRANSLATIONS Normal file
View file

@ -0,0 +1,124 @@
-------------------------------------------------------------------------------
--------- TRANSLATIONS - Ampache Translation Guide -----------
-------------------------------------------------------------------------------
Contents:
1. Introduction
a) Getting the Necessary tools
b) Quick Reference
2. Creating a New Translation
a) Translating
b) Creating a MO file
3. Updating an Existing Translation
a) Merging existing file
b) Generating the MO file
4. Questions?
Introduction:
Ampache uses gettext to handle translating between different languages if
you are interested in translating Ampache into a new language or updating
an existing translations simply follow the directions provided below.
A) Getting the Necessary Tools
Before attempting to translate Ampache into a new language we recommend
contacting translations@ampache.org to make sure that nobody else is
already working on a translation. Once you are ready to start your
translation you will need to get a few tools
- Gettext
- xgettext (Generates PO files)
- msgmerge (Merges old and new PO files)
- msgfmt (Generates the MO file from a PO file)
B) Quick Reference
Below are listed all of the commands you may have to run when working on
a translation
# Gather All info
Run locale/base/gather-messages.sh
# Create New po file
xgettext -n *.php -L PHP -o /tmp/mesasge.po
# Merge with existing po file
xgettext -o /tmp/messages.po -L PHP -n *.inc -j
# Combine Old & New po files
msgmerge old.po messages.po --output-file=new.po
# Generate MO file for use by gettext
msgfmt messages.po -o /tmp/messages.mo
Creating a New Translation:
A) Translating
I do my best to keep an up to date po file in /locale/base feel free to
use this file rather than attempting to generate your own. If you would
like to gather a new PO file simply run /locale/base/gather-messages.sh
(Linux only)
Once you have an up to date PO file you will need to figure out the
country code for the language you are translating into. There are many
lists on the web.
http://www.gnu.org/software/gettext/manual/html_chapter/gettext_16.html
Create the following directory structure and put your po file in the
LC_MESSAGES directory
/locale/<COUNTRY CODE>/LC_MESSAGES/
Start Translating!
C) Creating a MO File
Once you have finished translating the PO file you need to convert it into
a MO file in order for Gettext to be able to use it. Simply run the command
listed below.
msgfmt <DIR>messages.po -o <DIR>/messages.mo
Unfortunately currently Ampache doesn't automatically detect new languages
and thus you have to edit the code directly in order for it to pickup your
new language. Find /lib/preferences.php and then find "case 'lang':" under
the "create_preference_input" function and add a line for your own
language. For example to add en_US support add the following line
echo "\t<option value=\"en_US\" $en_US_lang>" . _("English") . "</option>\n";
Make sure that it comes after the <select> statement. This will be fixed
for future releases... Sorry :S
Updating an Existing Translation:
A) Merging existing file
If you are updating an existing PO file you will need to merge the new
file with the old so that you don't have to do everything over again.
simply run the following command.
msgmerge old.po messages.po --output-file=new.po
Once you have created the new PO file translate it as you normally would.
B) Generating the MO file
Because this is an existing translation you do not have to modify ampache
code at all simply run.
msgfmt <DIR>messages.po -o <DIR>messages.mo
And then check it in the web interface!
Questions:
If you have any questions or are unable to get gettext to work for you please
feel free to contact us at translations@ampache.org. Thanks!
Karl Vollmer
http://www.ampache.org
dev@ampache.org

6
locale/base/gather-messages.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/sh
find ../../ -name *.php > /tmp/filelist
find ../../ -name *.inc >> /tmp/filelist
xgettext -f /tmp/filelist -L PHP -o /tmp/messages.po

1801
locale/base/messages.po Normal file

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

92
localplay.php Normal file
View file

@ -0,0 +1,92 @@
<?php
/*
Copyright (c) 2004 Ampache.org
All rights reserved.
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*!
@header Song Document
@discussion Actually play files from albums, artists or just given
a bunch of id's.
Special thanx goes to Mike Payson and Jon Disnard for the means
to do this.
*/
require('modules/init.php');
/* If we are running a demo, quick while you still can! */
if (conf('demo_mode')) {
exit();
}
$web_path = conf('web_path');
if($user->prefs['play_type'] != 'local_play') {
echo "You dont have local play enabled!";
exit;
}
switch($_REQUEST['submit'])
{
case ' X ':
$action = "stop";
break;
case ' > ':
$action = "play";
break;
case ' = ':
$action = "pause";
break;
case '|< ':
$action = "prev";
break;
case ' >|':
$action = "next";
break;
case (substr_count($_REQUEST['submit'],"+") == '1'):
$amount = trim(substr($_REQUEST['submit'],2,strlen($_REQUEST['submit']-2)));
$action = "volplus";
break;
case (substr_count($_REQUEST['submit'],"-") == '1'):
$amount = trim(substr($_REQUEST['submit'],2,strlen($_REQUEST['submit']-2)));
$action = "volminus";
break;
case 'clear':
$action = "clear";
break;
case 'start':
$action = "start";
break;
case 'kill':
$action = "kill";
break;
default:
echo _("Unknown action requested") . ": '$_REQUEST[submit]'<br />";
exit;
}
$systr = conf('localplay_'.$action);
$systr = str_replace("%AMOUNT%",$amount,$systr);
if (conf('debug')) { log_event($user->username,'localplay',"Exec: $systr"); }
@exec($systr, $output);
$web_path = conf('web_path');
if($output)
print_r($output);
else
header("Location: $web_path");
?>

109
login.php Normal file
View file

@ -0,0 +1,109 @@
<?php
/*
This program is free software; you can redistribute it 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 more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
Login our friendly users
*/
$no_session = true;
require_once("modules/init.php");
set_site_preferences();
//
// So we check for a username and password first
//
if ( $_POST['username'] && $_POST['password'] ) {
if ($_POST['rememberme']) {
setcookie('amp_longsess', '1', time()+3600*24*30*120);
}
/* If we are in demo mode let's force auth success */
if (conf('demo_mode')) {
$auth['success'] = 1;
$auth['info']['username'] = "Admin- DEMO";
$auth['info']['fullname'] = "Administrative User";
$auth['info']['offset_limit'] = 25;
}
else {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$auth = authenticate($username, $password);
$user = new User($username);
if ($user->access === 'disabled') {
$auth['success'] = false;
$auth['error'] = "Error: User Disabled please contact Admin";
} // if user disabled
} // if we aren't in demo mode
}
//
// If we succeeded in authenticating, create a session
//
if ( ($auth['success'] == 1)) {
// $auth->info are the fields specified in the config file
// to retrieve for each user
make_local_session_only($auth);
//
// Not sure if it was me or php tripping out,
// but naming this 'user' didn't work at all
//
$_SESSION['userdata'] = $auth['info'];
// Make sure they are actually trying to get to this site
if (strstr($_POST['referrer'], conf('web_path')) AND !strstr($_POST['referrer'],"install.php") AND !strstr($_POST['referrer'],"login.php") AND !strstr($_POST['referrer'],"update.php")) {
header("Location: " . $_POST['referrer']);
exit();
} // if we've got a referrer
header("Location: " . conf('web_path') . "/index.php");
exit();
} // auth success
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">
<html lang="<?php echo conf('lang'); ?>">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo conf('site_charset'); ?>" />
<title> <?php echo conf('site_title'); ?> </title>
<?php show_template('style'); ?>
<script language="javascript">
function focus(){ document.login.username.focus(); }
</script>
</head>
<body bgcolor="<?php echo conf('bg_color1'); ?>" onload="focus();">
<?
require(conf('prefix') . "/templates/show_login_form.inc");
if (@is_readable(conf('prefix') . '/config/motd.php')) {
include conf('prefix') . '/config/motd.php';
}
?>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more